Changeset 965dc18 in mainline for kernel


Ignore:
Timestamp:
2008-12-05T19:59:03Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
49093a4
Parents:
0258e67
Message:

Merge sparc branch to trunk.

Location:
kernel
Files:
4 added
41 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/src/arm32.c

    r0258e67 r965dc18  
    8787
    8888#ifdef CONFIG_FB
    89         fb_init(machine_get_fb_address(), 640, 480, 1920, VISUAL_RGB_8_8_8);
     89        fb_properties_t prop = {
     90                .addr = machine_get_fb_address(),
     91                .offset = 0,
     92                .x = 640,
     93                .y = 480,
     94                .scan = 1920,
     95                .visual = VISUAL_RGB_8_8_8,
     96        };
     97        fb_init(&prop);
    9098#endif
    9199}
  • kernel/arch/ia32/src/drivers/vesa.c

    r0258e67 r965dc18  
    8787        }
    8888       
    89         fb_init(vesa_ph_addr, vesa_width, vesa_height, vesa_scanline, visual);
     89        fb_properties_t vesa_props = {
     90                .addr = vesa_ph_addr,
     91                .offset = 0,
     92                .x = vesa_width,
     93                .y = vesa_height,
     94                .scan = vesa_scanline,
     95                .visual = visual,
     96        };
     97        fb_init(&vesa_props);
    9098}
    9199
  • kernel/arch/mips32/src/mips32.c

    r0258e67 r965dc18  
    127127#ifdef CONFIG_FB
    128128        /* GXemul framebuffer */
    129         fb_init(0x12000000, 640, 480, 1920, VISUAL_RGB_8_8_8);
     129        fb_properties_t gxemul_prop = {
     130                .addr = 0x12000000,
     131                .offset = 0,
     132                .x = 640,
     133                .y = 480,
     134                .scan = 1920,
     135                .visual = VISUAL_RGB_8_8_8,
     136        };
     137        fb_init(&gxemul_prop);
    130138#endif
    131139        sysinfo_set_item_val("machine." STRING(MACHINE), NULL, 1);
  • kernel/arch/ppc32/src/ppc32.c

    r0258e67 r965dc18  
    9595                        panic("Unsupported bits per pixel");
    9696                }
    97                 fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.scanline, visual);
     97                fb_properties_t prop = {
     98                        .addr = bootinfo.screen.addr,
     99                        .offset = 0,
     100                        .x = bootinfo.screen.width,
     101                        .y = bootinfo.screen.height,
     102                        .scan = bootinfo.screen.scanline,
     103                        .visual = visual,
     104                };
     105                fb_init(&prop);
    98106               
    99107                /* Initialize IRQ routing */
     
    104112               
    105113                /* Initialize I/O controller */
    106                 cuda_init(device_assign_devno(), bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE);
     114                cuda_init(device_assign_devno(),
     115                    bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE);
    107116               
    108117                /* Merge all zones to 1 big zone */
     
    129138void userspace(uspace_arg_t *kernel_uarg)
    130139{
    131         userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, (uintptr_t) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (uintptr_t) kernel_uarg->uspace_entry);
     140        userspace_asm((uintptr_t) kernel_uarg->uspace_uarg,
     141            (uintptr_t) kernel_uarg->uspace_stack +
     142            THREAD_STACK_SIZE - SP_DELTA,
     143            (uintptr_t) kernel_uarg->uspace_entry);
    132144       
    133145        /* Unreachable */
  • kernel/arch/sparc64/Makefile.inc

    r0258e67 r965dc18  
    8181endif
    8282
     83ifeq ($(CONFIG_SGCN),y)
     84        DEFS += -DCONFIG_SGCN
     85endif
     86
     87ifeq ($(MACHINE),us)
     88    DEFS += -DUS
     89endif
     90
     91ifeq ($(MACHINE),us3)
     92        DEFS += -DUS3
     93endif
     94
    8395ARCH_SOURCES = \
    8496        arch/$(ARCH)/src/cpu/cpu.c \
     
    107119        arch/$(ARCH)/src/drivers/kbd.c \
    108120        arch/$(ARCH)/src/drivers/scr.c \
    109         arch/$(ARCH)/src/drivers/pci.c
     121        arch/$(ARCH)/src/drivers/sgcn.c \
     122        arch/$(ARCH)/src/drivers/pci.c
     123
    110124
    111125ifeq ($(CONFIG_SMP),y)
  • kernel/arch/sparc64/include/arch.h

    r0258e67 r965dc18  
    4242#define ASI_NUCLEUS_QUAD_LDD    0x24    /** ASI for 16-byte atomic loads. */
    4343#define ASI_DCACHE_TAG          0x47    /** ASI D-Cache Tag. */
    44 #define ASI_UPA_CONFIG          0x4a    /** ASI of the UPA_CONFIG register. */
     44#define ASI_ICBUS_CONFIG                0x4a    /** ASI of the UPA_CONFIG/FIREPLANE_CONFIG register. */
    4545
    4646#define NWINDOWS                8       /** Number of register window sets. */
  • kernel/arch/sparc64/include/asm.h

    r0258e67 r965dc18  
    137137}
    138138
     139/** Read STICK_compare Register.
     140 *
     141 * @return Value of STICK_compare register.
     142 */
     143static inline uint64_t stick_compare_read(void)
     144{
     145        uint64_t v;
     146       
     147        asm volatile ("rd %%asr25, %0\n" : "=r" (v));
     148       
     149        return v;
     150}
     151
     152/** Write STICK_compare Register.
     153 *
     154 * @param v New value of STICK_comapre register.
     155 */
     156static inline void stick_compare_write(uint64_t v)
     157{
     158        asm volatile ("wr %0, %1, %%asr25\n" : : "r" (v), "i" (0));
     159}
     160
    139161/** Read TICK Register.
    140162 *
     
    408430}
    409431
    410 /** Read UPA_CONFIG register.
    411  *
    412  * @return Value of the UPA_CONFIG register.
    413  */
    414 static inline uint64_t upa_config_read(void)
    415 {
    416         return asi_u64_read(ASI_UPA_CONFIG, 0);
    417 }
    418 
    419432extern void cpu_halt(void);
    420433extern void cpu_sleep(void);
  • kernel/arch/sparc64/include/cpu.h

    r0258e67 r965dc18  
    3636#define KERN_sparc64_CPU_H_
    3737
    38 #include <arch/types.h>
    39 #include <typedefs.h>
    40 #include <arch/register.h>
    41 #include <arch/asm.h>
    42 
    43 #ifdef CONFIG_SMP
    44 #include <arch/mm/cache.h>
    45 #endif
    46 
    4738#define MANUF_FUJITSU           0x04
    4839#define MANUF_ULTRASPARC        0x17    /**< UltraSPARC I, UltraSPARC II */
     
    5344#define IMPL_ULTRASPARCII_I     0x12
    5445#define IMPL_ULTRASPARCII_E     0x13
    55 #define IMPL_ULTRASPARCIII      0x15
     46#define IMPL_ULTRASPARCIII      0x14
     47#define IMPL_ULTRASPARCIII_PLUS 0x15
     48#define IMPL_ULTRASPARCIII_I    0x16
     49#define IMPL_ULTRASPARCIV       0x18
    5650#define IMPL_ULTRASPARCIV_PLUS  0x19
    5751
    5852#define IMPL_SPARC64V           0x5
    5953
     54#ifndef __ASM__
     55
     56#include <arch/types.h>
     57#include <typedefs.h>
     58#include <arch/register.h>
     59#include <arch/regdef.h>
     60#include <arch/asm.h>
     61
     62#ifdef CONFIG_SMP
     63#include <arch/mm/cache.h>
     64#endif
     65
    6066typedef struct {
    6167        uint32_t mid;                   /**< Processor ID as read from
    62                                              UPA_CONFIG. */
     68                                             UPA_CONFIG/FIREPLANE_CONFIG. */
    6369        ver_reg_t ver;
    6470        uint32_t clock_frequency;       /**< Processor frequency in Hz. */
     
    6773                                             matches this value. */
    6874} cpu_arch_t;
    69        
     75
     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;
     91#endif
     92}
     93
     94#endif 
     95
    7096#endif
    7197
  • kernel/arch/sparc64/include/drivers/kbd.h

    r0258e67 r965dc18  
    4242        KBD_UNKNOWN,
    4343        KBD_Z8530,
    44         KBD_NS16550
     44        KBD_NS16550,
     45        KBD_SGCN
    4546} kbd_type_t;
    4647
  • kernel/arch/sparc64/include/drivers/scr.h

    r0258e67 r965dc18  
    4343        SCR_ATYFB,
    4444        SCR_FFB,
    45         SCR_CGSIX
     45        SCR_CGSIX,
     46        SCR_XVR
    4647} scr_type_t;
    4748
  • kernel/arch/sparc64/include/mm/cache.h

    r0258e67 r965dc18  
    3939#include <mm/frame.h>
    4040
    41 #define dcache_flush_page(p) \
    42         dcache_flush_color(PAGE_COLOR((p)))
    43 #define dcache_flush_frame(p, f) \
    44         dcache_flush_tag(PAGE_COLOR((p)), ADDR2PFN((f)));
    45 
    46 extern void dcache_flush(void);
    47 extern void dcache_flush_color(int c);
    48 extern void dcache_flush_tag(int c, pfn_t tag);
    49 
    5041#endif
    5142
  • kernel/arch/sparc64/include/mm/cache_spec.h

    r0258e67 r965dc18  
    3939 * The following macros are valid for the following processors:
    4040 *
    41  *      UltraSPARC, UltraSPARC II, UltraSPARC IIi
     41 *      UltraSPARC, UltraSPARC II, UltraSPARC IIi, UltraSPARC III,
     42 *      UltraSPARC III+, UltraSPARC IV, UltraSPARC IV+
    4243 *
    4344 * Should we support other UltraSPARC processors, we need to make sure that
    4445 * the macros are defined correctly for them.
    4546 */
    46 
     47 
     48#if defined (US)
    4749#define DCACHE_SIZE             (16 * 1024)
     50#elif defined (US3)
     51#define DCACHE_SIZE             (64 * 1024)
     52#endif
    4853#define DCACHE_LINE_SIZE        32     
    49 
    50 #define ICACHE_SIZE             (16 * 1024)
    51 #define ICACHE_WAYS             2
    52 #define ICACHE_LINE_SIZE        32
    5354
    5455#endif
  • kernel/arch/sparc64/include/mm/frame.h

    r0258e67 r965dc18  
    6060        uintptr_t address;
    6161        struct {
     62#if defined (US)
    6263                unsigned : 23;
    6364                uint64_t pfn : 28;              /**< Physical Frame Number. */
     65#elif defined (US3)
     66                unsigned : 21;
     67                uint64_t pfn : 30;              /**< Physical Frame Number. */
     68#endif
    6469                unsigned offset : 13;           /**< Offset. */
    6570        } __attribute__ ((packed));
  • kernel/arch/sparc64/include/mm/mmu.h

    r0258e67 r965dc18  
    3636#define KERN_sparc64_MMU_H_
    3737
     38#if defined(US)
    3839/* LSU Control Register ASI. */
    3940#define ASI_LSU_CONTROL_REG             0x45    /**< Load/Store Unit Control Register. */
     41#endif
    4042
    4143/* I-MMU ASIs. */
     
    5355#define VA_IMMU_TSB_BASE                0x28    /**< IMMU TSB base register. */
    5456#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
    5562
    5663/* D-MMU ASIs. */
     
    7481#define VA_DMMU_VA_WATCHPOINT_REG       0x38    /**< DMMU VA data watchpoint register. */
    7582#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
    7688
    7789#ifndef __ASM__
     
    8193#include <arch/types.h>
    8294
     95#if defined(US)
    8396/** LSU Control Register. */
    8497typedef union {
     
    101114        } __attribute__ ((packed));
    102115} lsu_cr_reg_t;
     116#endif /* US */
    103117
    104118#endif /* !def __ASM__ */
  • kernel/arch/sparc64/include/mm/tlb.h

    r0258e67 r965dc18  
    3636#define KERN_sparc64_TLB_H_
    3737
     38#if defined (US)
    3839#define ITLB_ENTRY_COUNT                64
    3940#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
    4048
    4149#define MEM_CONTEXT_KERNEL              0
     
    5462#define TLB_DEMAP_PAGE          0
    5563#define TLB_DEMAP_CONTEXT       1
     64#if defined (US3)
     65#define TLB_DEMAP_ALL           2
     66#endif
    5667
    5768#define TLB_DEMAP_TYPE_SHIFT    6
     
    6172#define TLB_DEMAP_SECONDARY     1
    6273#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
    6386
    6487#define TLB_DEMAP_CONTEXT_SHIFT 4
     
    77100#include <arch/barrier.h>
    78101#include <arch/types.h>
     102#include <arch/register.h>
     103#include <arch/cpu.h>
    79104
    80105union tlb_context_reg {
     
    91116
    92117/** I-/D-TLB Data Access Address in Alternate Space. */
     118
     119#if defined (US)
     120
    93121union tlb_data_access_addr {
    94122        uint64_t value;
     
    99127        } __attribute__ ((packed));
    100128};
    101 typedef union tlb_data_access_addr tlb_data_access_addr_t;
    102 typedef union tlb_data_access_addr tlb_tag_read_addr_t;
     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
    103176
    104177/** I-/D-TLB Tag Read Register. */
     
    119192        struct {
    120193                uint64_t vpn: 51;       /**< Virtual Address bits 63:13. */
     194#if defined (US)
    121195                unsigned : 6;           /**< Ignored. */
    122196                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
    123201                unsigned context : 2;   /**< Context register selection. */
    124202                unsigned : 4;           /**< Zero. */
     
    131209        uint64_t value;
    132210        struct {
     211#if defined (US)
    133212                unsigned long : 40;     /**< Implementation dependent. */
    134213                unsigned asi : 8;       /**< ASI. */
    135214                unsigned : 2;
    136215                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
    137224                unsigned e : 1;         /**< Side-effect bit. */
    138225                unsigned ct : 2;        /**< Context Register selection. */
     
    145232typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
    146233
     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
    147278/** Read MMU Primary Context Register.
    148279 *
    149  * @return Current value of Primary Context Register.
     280 * @return              Current value of Primary Context Register.
    150281 */
    151282static inline uint64_t mmu_primary_context_read(void)
     
    156287/** Write MMU Primary Context Register.
    157288 *
    158  * @param v New value of Primary Context Register.
     289 * @param v             New value of Primary Context Register.
    159290 */
    160291static inline void mmu_primary_context_write(uint64_t v)
     
    166297/** Read MMU Secondary Context Register.
    167298 *
    168  * @return Current value of Secondary Context Register.
     299 * @return              Current value of Secondary Context Register.
    169300 */
    170301static inline uint64_t mmu_secondary_context_read(void)
     
    175306/** Write MMU Primary Context Register.
    176307 *
    177  * @param v New value of Primary Context Register.
     308 * @param v             New value of Primary Context Register.
    178309 */
    179310static inline void mmu_secondary_context_write(uint64_t v)
     
    183314}
    184315
     316#if defined (US)
     317
    185318/** Read IMMU TLB Data Access Register.
    186319 *
    187  * @param entry TLB Entry index.
    188  *
    189  * @return Current value of specified IMMU TLB Data Access Register.
     320 * @param entry         TLB Entry index.
     321 *
     322 * @return              Current value of specified IMMU TLB Data Access
     323 *                      Register.
    190324 */
    191325static inline uint64_t itlb_data_access_read(index_t entry)
    192326{
    193         tlb_data_access_addr_t reg;
     327        itlb_data_access_addr_t reg;
    194328       
    195329        reg.value = 0;
     
    200334/** Write IMMU TLB Data Access Register.
    201335 *
    202  * @param entry TLB Entry index.
    203  * @param value Value to be written.
     336 * @param entry         TLB Entry index.
     337 * @param value         Value to be written.
    204338 */
    205339static inline void itlb_data_access_write(index_t entry, uint64_t value)
    206340{
    207         tlb_data_access_addr_t reg;
     341        itlb_data_access_addr_t reg;
    208342       
    209343        reg.value = 0;
     
    215349/** Read DMMU TLB Data Access Register.
    216350 *
    217  * @param entry TLB Entry index.
    218  *
    219  * @return Current value of specified DMMU TLB Data Access Register.
     351 * @param entry         TLB Entry index.
     352 *
     353 * @return              Current value of specified DMMU TLB Data Access
     354 *                      Register.
    220355 */
    221356static inline uint64_t dtlb_data_access_read(index_t entry)
    222357{
    223         tlb_data_access_addr_t reg;
     358        dtlb_data_access_addr_t reg;
    224359       
    225360        reg.value = 0;
     
    230365/** Write DMMU TLB Data Access Register.
    231366 *
    232  * @param entry TLB Entry index.
    233  * @param value Value to be written.
     367 * @param entry         TLB Entry index.
     368 * @param value         Value to be written.
    234369 */
    235370static inline void dtlb_data_access_write(index_t entry, uint64_t value)
    236371{
    237         tlb_data_access_addr_t reg;
     372        dtlb_data_access_addr_t reg;
    238373       
    239374        reg.value = 0;
     
    245380/** Read IMMU TLB Tag Read Register.
    246381 *
    247  * @param entry TLB Entry index.
    248  *
    249  * @return Current value of specified IMMU TLB Tag Read Register.
     382 * @param entry         TLB Entry index.
     383 *
     384 * @return              Current value of specified IMMU TLB Tag Read Register.
    250385 */
    251386static inline uint64_t itlb_tag_read_read(index_t entry)
    252387{
    253         tlb_tag_read_addr_t tag;
     388        itlb_tag_read_addr_t tag;
    254389
    255390        tag.value = 0;
     
    260395/** Read DMMU TLB Tag Read Register.
    261396 *
    262  * @param entry TLB Entry index.
    263  *
    264  * @return Current value of specified DMMU TLB Tag Read Register.
     397 * @param entry         TLB Entry index.
     398 *
     399 * @return              Current value of specified DMMU TLB Tag Read Register.
    265400 */
    266401static inline uint64_t dtlb_tag_read_read(index_t entry)
    267402{
    268         tlb_tag_read_addr_t tag;
     403        dtlb_tag_read_addr_t tag;
    269404
    270405        tag.value = 0;
     
    273408}
    274409
     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, index_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, index_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, index_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, index_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, index_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, index_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
    275521/** Write IMMU TLB Tag Access Register.
    276522 *
    277  * @param v Value to be written.
     523 * @param v             Value to be written.
    278524 */
    279525static inline void itlb_tag_access_write(uint64_t v)
     
    285531/** Read IMMU TLB Tag Access Register.
    286532 *
    287  * @return Current value of IMMU TLB Tag Access Register.
     533 * @return              Current value of IMMU TLB Tag Access Register.
    288534 */
    289535static inline uint64_t itlb_tag_access_read(void)
     
    294540/** Write DMMU TLB Tag Access Register.
    295541 *
    296  * @param v Value to be written.
     542 * @param v             Value to be written.
    297543 */
    298544static inline void dtlb_tag_access_write(uint64_t v)
     
    304550/** Read DMMU TLB Tag Access Register.
    305551 *
    306  * @return Current value of DMMU TLB Tag Access Register.
     552 * @return              Current value of DMMU TLB Tag Access Register.
    307553 */
    308554static inline uint64_t dtlb_tag_access_read(void)
     
    314560/** Write IMMU TLB Data in Register.
    315561 *
    316  * @param v Value to be written.
     562 * @param v             Value to be written.
    317563 */
    318564static inline void itlb_data_in_write(uint64_t v)
     
    324570/** Write DMMU TLB Data in Register.
    325571 *
    326  * @param v Value to be written.
     572 * @param v             Value to be written.
    327573 */
    328574static inline void dtlb_data_in_write(uint64_t v)
     
    334580/** Read ITLB Synchronous Fault Status Register.
    335581 *
    336  * @return Current content of I-SFSR register.
     582 * @return              Current content of I-SFSR register.
    337583 */
    338584static inline uint64_t itlb_sfsr_read(void)
     
    343589/** Write ITLB Synchronous Fault Status Register.
    344590 *
    345  * @param v New value of I-SFSR register.
     591 * @param v             New value of I-SFSR register.
    346592 */
    347593static inline void itlb_sfsr_write(uint64_t v)
     
    353599/** Read DTLB Synchronous Fault Status Register.
    354600 *
    355  * @return Current content of D-SFSR register.
     601 * @return              Current content of D-SFSR register.
    356602 */
    357603static inline uint64_t dtlb_sfsr_read(void)
     
    362608/** Write DTLB Synchronous Fault Status Register.
    363609 *
    364  * @param v New value of D-SFSR register.
     610 * @param v             New value of D-SFSR register.
    365611 */
    366612static inline void dtlb_sfsr_write(uint64_t v)
     
    372618/** Read DTLB Synchronous Fault Address Register.
    373619 *
    374  * @return Current content of D-SFAR register.
     620 * @return              Current content of D-SFAR register.
    375621 */
    376622static inline uint64_t dtlb_sfar_read(void)
     
    381627/** Perform IMMU TLB Demap Operation.
    382628 *
    383  * @param type Selects between context and page demap.
     629 * @param type          Selects between context and page demap (and entire MMU
     630 *                      demap on US3).
    384631 * @param context_encoding Specifies which Context register has Context ID for
    385  *      demap.
    386  * @param page Address which is on the page to be demapped.
     632 *                      demap.
     633 * @param page          Address which is on the page to be demapped.
    387634 */
    388635static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
     
    398645        da.vpn = pg.vpn;
    399646       
    400         asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);     /* da.value is the
    401                                                          * address within the
    402                                                          * ASI */
     647        /* da.value is the address within the ASI */
     648        asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
     649
    403650        flush_pipeline();
    404651}
     
    406653/** Perform DMMU TLB Demap Operation.
    407654 *
    408  * @param type Selects between context and page demap.
     655 * @param type          Selects between context and page demap (and entire MMU
     656 *                      demap on US3).
    409657 * @param context_encoding Specifies which Context register has Context ID for
    410  *       demap.
    411  * @param page Address which is on the page to be demapped.
     658 *                      demap.
     659 * @param page          Address which is on the page to be demapped.
    412660 */
    413661static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
     
    423671        da.vpn = pg.vpn;
    424672       
    425         asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);     /* da.value is the
    426                                                          * address within the
    427                                                          * ASI */
     673        /* da.value is the address within the ASI */
     674        asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
     675
    428676        membar();
    429677}
    430678
    431 extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate);
    432 extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate);
    433 extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate);
    434 
    435 extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
     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);
    436684
    437685extern void dump_sfsr_and_sfar(void);
  • kernel/arch/sparc64/include/mm/tsb.h

    r0258e67 r965dc18  
    108108}
    109109
     110#if defined (US3)
     111
     112/** Write DTSB Primary Extension register.
     113 *
     114 * @param v New content of the DTSB Primary Extension register.
     115 */
     116static inline void dtsb_primary_extension_write(uint64_t v)
     117{
     118        asi_u64_write(ASI_DMMU, VA_DMMU_PRIMARY_EXTENSION, v);
     119}
     120
     121/** Write DTSB Secondary Extension register.
     122 *
     123 * @param v New content of the DTSB Secondary Extension register.
     124 */
     125static inline void dtsb_secondary_extension_write(uint64_t v)
     126{
     127        asi_u64_write(ASI_DMMU, VA_DMMU_SECONDARY_EXTENSION, v);
     128}
     129
     130/** Write DTSB Nucleus Extension register.
     131 *
     132 * @param v New content of the DTSB Nucleus Extension register.
     133 */
     134static inline void dtsb_nucleus_extension_write(uint64_t v)
     135{
     136        asi_u64_write(ASI_DMMU, VA_DMMU_NUCLEUS_EXTENSION, v);
     137}
     138
     139/** Write ITSB Primary Extension register.
     140 *
     141 * @param v New content of the ITSB Primary Extension register.
     142 */
     143static inline void itsb_primary_extension_write(uint64_t v)
     144{
     145        asi_u64_write(ASI_IMMU, VA_IMMU_PRIMARY_EXTENSION, v);
     146}
     147
     148/** Write ITSB Nucleus Extension register.
     149 *
     150 * @param v New content of the ITSB Nucleus Extension register.
     151 */
     152static inline void itsb_nucleus_extension_write(uint64_t v)
     153{
     154        asi_u64_write(ASI_IMMU, VA_IMMU_NUCLEUS_EXTENSION, v);
     155}
     156
     157#endif
     158
    110159/* Forward declarations. */
    111160struct as;
  • kernel/arch/sparc64/include/mm/tte.h

    r0258e67 r965dc18  
    5151#include <arch/types.h>
    5252
     53/* TTE tag's VA_tag field contains bits <63:VA_TAG_PAGE_SHIFT> of the VA */
    5354#define VA_TAG_PAGE_SHIFT       22
    5455
     
    7677                unsigned ie : 1;        /**< Invert Endianness. */
    7778                unsigned soft2 : 9;     /**< Software defined field. */
     79#if defined (US)
    7880                unsigned diag : 9;      /**< Diagnostic data. */
    7981                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 */
     85#endif
    8086                unsigned soft : 6;      /**< Software defined field. */
    8187                unsigned l : 1;         /**< Lock. */
  • kernel/arch/sparc64/include/regdef.h

    r0258e67 r965dc18  
    5656#define WSTATE_OTHER(n)         ((n) << 3)
    5757
    58 #define UPA_CONFIG_MID_SHIFT    17
    59 #define UPA_CONFIG_MID_MASK     0x1f
     58/*
     59 * The following definitions concern the UPA_CONFIG register on US and the
     60 * FIREPLANE_CONFIG register on US3.
     61 */
     62#define ICBUS_CONFIG_MID_SHIFT    17
    6063
    6164#endif
  • kernel/arch/sparc64/include/register.h

    r0258e67 r965dc18  
    118118typedef union fprs_reg fprs_reg_t;
    119119
    120 /** UPA_CONFIG register.
    121  *
    122  * Note that format of this register differs significantly from
    123  * processor version to version. The format defined here
    124  * is the common subset for all supported processor versions.
    125  */
    126 union upa_config {
    127         uint64_t value;
    128         struct {
    129                 uint64_t : 34;
    130                 unsigned pcon : 8;      /**< Processor configuration. */
    131                 unsigned mid : 5;       /**< Module (processor) ID register. */
    132                 unsigned pcap : 17;     /**< Processor capabilities. */
    133         } __attribute__ ((packed));
    134 };
    135 typedef union upa_config upa_config_t;
    136 
    137120#endif
    138121
  • kernel/arch/sparc64/include/trap/interrupt.h

    r0258e67 r965dc18  
    5050
    5151/* Interrupt ASI registers. */
    52 #define ASI_UDB_INTR_W                  0x77
     52#define ASI_INTR_W                      0x77
    5353#define ASI_INTR_DISPATCH_STATUS        0x48
    54 #define ASI_UDB_INTR_R                  0x7f
     54#define ASI_INTR_R                      0x7f
    5555#define ASI_INTR_RECEIVE                0x49
    5656
    57 /* VA's used with ASI_UDB_INTR_W register. */
     57/* VA's used with ASI_INTR_W register. */
     58#if defined (US)
    5859#define ASI_UDB_INTR_W_DATA_0   0x40
    5960#define ASI_UDB_INTR_W_DATA_1   0x50
    6061#define ASI_UDB_INTR_W_DATA_2   0x60
    61 #define ASI_UDB_INTR_W_DISPATCH 0x70
     62#elif defined (US3)
     63#define VA_INTR_W_DATA_0        0x40
     64#define VA_INTR_W_DATA_1        0x48
     65#define VA_INTR_W_DATA_2        0x50
     66#define VA_INTR_W_DATA_3        0x58
     67#define VA_INTR_W_DATA_4        0x60
     68#define VA_INTR_W_DATA_5        0x68
     69#define VA_INTR_W_DATA_6        0x80
     70#define VA_INTR_W_DATA_7        0x88
     71#endif
     72#define VA_INTR_W_DISPATCH      0x70
    6273
    63 /* VA's used with ASI_UDB_INTR_R register. */
     74/* VA's used with ASI_INTR_R register. */
     75#if defined(US)
    6476#define ASI_UDB_INTR_R_DATA_0   0x40
    6577#define ASI_UDB_INTR_R_DATA_1   0x50
    6678#define ASI_UDB_INTR_R_DATA_2   0x60
     79#elif defined (US3)
     80#define VA_INTR_R_DATA_0        0x40
     81#define VA_INTR_R_DATA_1        0x48
     82#define VA_INTR_R_DATA_2        0x50
     83#define VA_INTR_R_DATA_3        0x58
     84#define VA_INTR_R_DATA_4        0x60
     85#define VA_INTR_R_DATA_5        0x68
     86#define VA_INTR_R_DATA_6        0x80
     87#define VA_INTR_R_DATA_7        0x88
     88#endif
    6789
    6890/* Shifts in the Interrupt Vector Dispatch virtual address. */
  • kernel/arch/sparc64/src/console.c

    r0258e67 r965dc18  
    3939#include <arch/drivers/kbd.h>
    4040
     41#include <arch/drivers/sgcn.h>
     42
    4143#ifdef CONFIG_Z8530
    4244#include <genarch/kbd/z8530.h>
     
    5557#include <arch.h>
    5658#include <panic.h>
     59#include <func.h>
    5760#include <print.h>
    5861
    5962#define KEYBOARD_POLL_PAUSE     50000   /* 50ms */
    6063
    61 /** Initialize kernel console to use framebuffer and keyboard directly. */
    62 void standalone_sparc64_console_init(void)
     64/**
     65 * Initialize kernel console to use framebuffer and keyboard directly.
     66 * Called on UltraSPARC machines with standard keyboard and framebuffer.
     67 *
     68 * @param aliases       the "/aliases" OBP node
     69 */
     70static void standard_console_init(ofw_tree_node_t *aliases)
    6371{
    6472        stdin = NULL;
    6573
    66         ofw_tree_node_t *aliases;
    6774        ofw_tree_property_t *prop;
    6875        ofw_tree_node_t *screen;
    6976        ofw_tree_node_t *keyboard;
    70        
    71         aliases = ofw_tree_lookup("/aliases");
    72         if (!aliases)
    73                 panic("Can't find /aliases.\n");
    7477       
    7578        prop = ofw_tree_getprop(aliases, "screen");
     
    9699}
    97100
     101/** Initilize I/O on the Serengeti machine. */
     102static void serengeti_init(void)
     103{
     104        sgcn_init();
     105}
     106
     107/**
     108 * Initialize input/output. Auto-detects the type of machine
     109 * and calls the appropriate I/O init routine.
     110 */
     111void standalone_sparc64_console_init(void)
     112{
     113        ofw_tree_node_t *aliases;
     114        ofw_tree_property_t *prop;
     115       
     116        aliases = ofw_tree_lookup("/aliases");
     117        if (!aliases)
     118                panic("Can't find /aliases.\n");
     119       
     120        /* "def-cn" = "default console" */
     121        prop = ofw_tree_getprop(aliases, "def-cn");
     122       
     123        if ((!prop) || (!prop->value) || (strcmp(prop->value, "/sgcn") != 0)) {
     124                standard_console_init(aliases);
     125        } else {
     126                serengeti_init();
     127        }
     128}
     129
     130
    98131/** Kernel thread for polling keyboard.
    99132 *
     
    130163#endif
    131164#endif
     165#ifdef CONFIG_SGCN
     166                if (kbd_type == KBD_SGCN)
     167                        sgcn_poll();
     168#endif
    132169                thread_usleep(KEYBOARD_POLL_PAUSE);
    133170        }
     
    150187                break;
    151188#endif
     189#ifdef CONFIG_SGCN
     190        case KBD_SGCN:
     191                sgcn_grab();
     192                break;
     193#endif
    152194        default:
    153195                break;
     
    171213                break;
    172214#endif
     215#ifdef CONFIG_SGCN
     216        case KBD_SGCN:
     217                sgcn_release();
     218                break;
     219#endif
    173220        default:
    174221                break;
  • kernel/arch/sparc64/src/cpu/cpu.c

    r0258e67 r965dc18  
    3333 */
    3434
     35#include <arch/cpu_family.h>
    3536#include <cpu.h>
    3637#include <arch.h>
     
    3839#include <arch/drivers/tick.h>
    3940#include <print.h>
     41#include <arch/cpu_node.h>
     42
     43/**
     44 * Finds out the clock frequency of the current CPU.
     45 *
     46 * @param node  node representing the current CPU in the OFW tree
     47 * @return      clock frequency if "node" is the current CPU and no error
     48 *              occurs, -1 if "node" is not the current CPU or on error
     49 */
     50static int find_cpu_frequency(ofw_tree_node_t *node)
     51{
     52        ofw_tree_property_t *prop;
     53        uint32_t mid;
     54
     55        /* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */
     56        prop = ofw_tree_getprop(node, "upa-portid");
     57        if ((!prop) || (!prop->value))
     58                prop = ofw_tree_getprop(node, "portid");
     59        if ((!prop) || (!prop->value))
     60                prop = ofw_tree_getprop(node, "cpuid");
     61       
     62        if (prop && prop->value) {
     63                mid = *((uint32_t *) prop->value);
     64                if (mid == CPU->arch.mid) {
     65                        prop = ofw_tree_getprop(node, "clock-frequency");
     66                        if (prop && prop->value) {
     67                                return *((uint32_t *) prop->value);
     68                        }
     69                }
     70        }
     71       
     72        return -1;
     73}
    4074
    4175/** Perform sparc64 specific initialization of the processor structure for the
     
    4579{
    4680        ofw_tree_node_t *node;
    47         uint32_t mid;
    4881        uint32_t clock_frequency = 0;
    49         upa_config_t upa_config;
    5082       
    51         upa_config.value = upa_config_read();
    52         CPU->arch.mid = upa_config.mid;
     83        CPU->arch.mid = read_mid();
    5384       
    5485        /*
    5586         * Detect processor frequency.
    5687         */
    57         node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
    58         while (node) {
    59                 ofw_tree_property_t *prop;
     88        if (is_us() || is_us_iii()) {
     89                node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
     90                while (node) {
     91                        int f = find_cpu_frequency(node);
     92                        if (f != -1)
     93                                clock_frequency = (uint32_t) f;
     94                        node = ofw_tree_find_peer_by_device_type(node, "cpu");
     95                }
     96        } else if (is_us_iv()) {
     97                node = ofw_tree_find_child(cpus_parent(), "cmp");
     98                while (node) {
     99                        int f;
     100                        f = find_cpu_frequency(
     101                                ofw_tree_find_child(node, "cpu@0"));
     102                        if (f != -1)
     103                                clock_frequency = (uint32_t) f;
     104                        f = find_cpu_frequency(
     105                                ofw_tree_find_child(node, "cpu@1"));
     106                        if (f != -1)
     107                                clock_frequency = (uint32_t) f;
     108                        node = ofw_tree_find_peer_by_name(node, "cmp");
     109                }
     110        }
    60111               
    61                 prop = ofw_tree_getprop(node, "upa-portid");
    62                 if (prop && prop->value) {
    63                         mid = *((uint32_t *) prop->value);
    64                         if (mid == CPU->arch.mid) {
    65                                 prop = ofw_tree_getprop(node,
    66                                     "clock-frequency");
    67                                 if (prop && prop->value)
    68                                         clock_frequency = *((uint32_t *)
    69                                             prop->value);
    70                         }
    71                 }
    72                 node = ofw_tree_find_peer_by_device_type(node, "cpu");
    73         }
    74 
    75112        CPU->arch.clock_frequency = clock_frequency;
    76113        tick_init();
     
    125162                impl = "UltraSPARC III";
    126163                break;
     164        case IMPL_ULTRASPARCIII_PLUS:
     165                impl = "UltraSPARC III+";
     166                break;
     167        case IMPL_ULTRASPARCIII_I:
     168                impl = "UltraSPARC IIIi";
     169                break;
     170        case IMPL_ULTRASPARCIV:
     171                impl = "UltraSPARC IV";
     172                break;
    127173        case IMPL_ULTRASPARCIV_PLUS:
    128174                impl = "UltraSPARC IV+";
  • kernel/arch/sparc64/src/ddi/ddi.c

    r0258e67 r965dc18  
    4242 *
    4343 * @param task Task.
    44  * @param ioaddr Startign I/O space address.
     44 * @param ioaddr Starting I/O space address.
    4545 * @param size Size of the enabled I/O range.
    4646 *
  • kernel/arch/sparc64/src/drivers/scr.c

    r0258e67 r965dc18  
    5656{
    5757        ofw_tree_property_t *prop;
     58        ofw_pci_reg_t *pci_reg;
     59        ofw_pci_reg_t pci_abs_reg;
     60        ofw_upa_reg_t *upa_reg;
     61        ofw_sbus_reg_t *sbus_reg;
    5862        const char *name;
    5963       
     
    6266        if (strcmp(name, "SUNW,m64B") == 0)
    6367                scr_type = SCR_ATYFB;
     68        else if (strcmp(name, "SUNW,XVR-100") == 0)
     69                scr_type = SCR_XVR;
    6470        else if (strcmp(name, "SUNW,ffb") == 0)
    6571                scr_type = SCR_FFB;
     
    6874       
    6975        if (scr_type == SCR_UNKNOWN) {
    70                 printf("Unknown keyboard device.\n");
     76                printf("Unknown screen device.\n");
    7177                return;
    7278        }
     
    107113                }
    108114       
    109                 ofw_pci_reg_t *fb_reg = &((ofw_pci_reg_t *) prop->value)[1];
    110                 ofw_pci_reg_t abs_reg;
    111                
    112                 if (!ofw_pci_reg_absolutize(node, fb_reg, &abs_reg)) {
     115                pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
     116               
     117                if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
    113118                        printf("Failed to absolutize fb register.\n");
    114119                        return;
    115120                }
    116121       
    117                 if (!ofw_pci_apply_ranges(node->parent, &abs_reg , &fb_addr)) {
     122                if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
     123                    &fb_addr)) {
    118124                        printf("Failed to determine screen address.\n");
    119125                        return;
     
    143149               
    144150                break;
     151        case SCR_XVR:
     152                if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
     153                        printf("Too few screen registers.\n");
     154                        return;
     155                }
     156       
     157                pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
     158               
     159                if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
     160                        printf("Failed to absolutize fb register.\n");
     161                        return;
     162                }
     163       
     164                if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
     165                    &fb_addr)) {
     166                        printf("Failed to determine screen address.\n");
     167                        return;
     168                }
     169
     170                switch (fb_depth) {
     171                case 8:
     172                        fb_scanline = fb_linebytes * (fb_depth >> 3);
     173                        visual = VISUAL_SB1500_PALETTE;
     174                        break;
     175                case 16:
     176                        fb_scanline = fb_linebytes * (fb_depth >> 3);
     177                        visual = VISUAL_RGB_5_6_5;
     178                        break;
     179                case 24:
     180                        fb_scanline = fb_linebytes * 4;
     181                        visual = VISUAL_RGB_8_8_8_0;
     182                        break;
     183                case 32:
     184                        fb_scanline = fb_linebytes * (fb_depth >> 3);
     185                        visual = VISUAL_RGB_0_8_8_8;
     186                        break;
     187                default:
     188                        printf("Unsupported bits per pixel.\n");
     189                        return;
     190                }
     191               
     192                break;
    145193        case SCR_FFB:   
    146194                fb_scanline = 8192;
    147195                visual = VISUAL_BGR_0_8_8_8;
    148196
    149                 ofw_upa_reg_t *reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
    150                 if (!ofw_upa_apply_ranges(node->parent, reg, &fb_addr)) {
     197                upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
     198                if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) {
    151199                        printf("Failed to determine screen address.\n");
    152200                        return;
     
    165213                }
    166214               
    167                 ofw_sbus_reg_t *cg6_reg = &((ofw_sbus_reg_t *) prop->value)[0];
    168                 if (!ofw_sbus_apply_ranges(node->parent, cg6_reg, &fb_addr)) {
     215                sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0];
     216                if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) {
    169217                        printf("Failed to determine screen address.\n");
    170218                        return;
     
    176224        }
    177225
    178         fb_init(fb_addr, fb_width, fb_height, fb_scanline, visual);
     226        fb_properties_t props = {
     227                .addr = fb_addr,
     228                .offset = 0,
     229                .x = fb_width,
     230                .y = fb_height,
     231                .scan = fb_scanline,
     232                .visual = visual,
     233        };
     234        fb_init(&props);
    179235}
    180236
  • kernel/arch/sparc64/src/drivers/tick.c

    r0258e67 r965dc18  
    4646#define TICK_RESTART_TIME       50      /* Worst case estimate. */
    4747
    48 /** Initialize tick interrupt. */
     48/** Initialize tick and stick interrupt. */
    4949void tick_init(void)
    5050{
     51        /* initialize TICK interrupt */
    5152        tick_compare_reg_t compare;
    52        
     53
    5354        interrupt_register(14, "tick_int", tick_interrupt);
    5455        compare.int_dis = false;
     
    5758        tick_compare_write(compare.value);
    5859        tick_write(0);
     60
     61#if defined (US3)
     62        /* disable STICK interrupts and clear any pending ones */
     63        tick_compare_reg_t stick_compare;
     64        softint_reg_t clear;
     65
     66        stick_compare.value = stick_compare_read();
     67        stick_compare.int_dis = true;
     68        stick_compare.tick_cmpr = 0;
     69        stick_compare_write(stick_compare.value);
     70
     71        clear.value = 0;
     72        clear.stick_int = 1;
     73        clear_softint_write(clear.value);
     74#endif
    5975}
    6076
     
    6884        softint_reg_t softint, clear;
    6985        uint64_t drift;
    70        
     86
    7187        softint.value = softint_read();
    7288       
  • kernel/arch/sparc64/src/mm/as.c

    r0258e67 r965dc18  
    165165        tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH;
    166166        dtsb_base_write(tsb_base.value);
     167       
     168#if defined (US3)
     169        /*
     170         * Clear the extension registers.
     171         * In HelenOS, primary and secondary context registers contain
     172         * equal values and kernel misses (context 0, ie. the nucleus context)
     173         * are excluded from the TSB miss handler, so it makes no sense
     174         * to have separate TSBs for primary, secondary and nucleus contexts.
     175         * Clearing the extension registers will ensure that the value of the
     176         * TSB Base register will be used as an address of TSB, making the code
     177         * compatible with the US port.
     178         */
     179        itsb_primary_extension_write(0);
     180        itsb_nucleus_extension_write(0);
     181        dtsb_primary_extension_write(0);
     182        dtsb_secondary_extension_write(0);
     183        dtsb_nucleus_extension_write(0);
     184#endif
    167185#endif
    168186}
  • kernel/arch/sparc64/src/mm/cache.S

    r0258e67 r965dc18  
    4848        ! beware SF Erratum #51, do not put the MEMBAR here
    4949        nop                             
    50 
    51 /** Flush only D-cache lines of one virtual color.
    52  *
    53  * @param o0    Virtual color to be flushed.
    54  */
    55 .global dcache_flush_color
    56 dcache_flush_color:
    57         mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
    58         set DCACHE_SIZE / 2, %g2
    59         sllx %g2, %o0, %g2
    60         sub %g2, DCACHE_LINE_SIZE, %g2
    61 0:      stxa %g0, [%g2] ASI_DCACHE_TAG
    62         membar #Sync
    63         subcc %g1, 1, %g1
    64         bnz,pt %xcc, 0b
    65         sub %g2, DCACHE_LINE_SIZE, %g2
    66         retl
    67         nop
    68 
    69 /** Flush only D-cache lines of one virtual color and one tag.
    70  *
    71  * @param o0    Virtual color to lookup the tag.
    72  * @param o1    Tag of the cachelines to be flushed.
    73  */
    74 .global dcache_flush_tag
    75 dcache_flush_tag:
    76         mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
    77         set DCACHE_SIZE / 2, %g2
    78         sllx %g2, %o0, %g2
    79         sub %g2, DCACHE_LINE_SIZE, %g2
    80 0:      ldxa [%g2] ASI_DCACHE_TAG, %g3
    81         srlx %g3, DCACHE_TAG_SHIFT, %g3
    82         cmp %g3, %o1
    83         bnz 1f
    84         nop
    85         stxa %g0, [%g2] ASI_DCACHE_TAG
    86         membar #Sync
    87 1:      subcc %g1, 1, %g1
    88         bnz,pt %xcc, 0b
    89         sub %g2, DCACHE_LINE_SIZE, %g2
    90         retl
    91         nop
  • kernel/arch/sparc64/src/mm/page.c

    r0258e67 r965dc18  
    5353        uintptr_t phys_page;
    5454        int pagesize_code;
    55 } bsp_locked_dtlb_entry[DTLB_ENTRY_COUNT];
     55} bsp_locked_dtlb_entry[DTLB_MAX_LOCKED_ENTRIES];
    5656
    5757/** Number of entries in bsp_locked_dtlb_entry array. */
     
    167167/** @}
    168168 */
     169
  • kernel/arch/sparc64/src/mm/tlb.c

    r0258e67 r965dc18  
    5555#endif
    5656
    57 static void dtlb_pte_copy(pte_t *t, index_t index, bool ro);
    58 static void itlb_pte_copy(pte_t *t, index_t index);
    59 static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
    60     const char *str);
    61 static void do_fast_data_access_mmu_miss_fault(istate_t *istate,
    62     tlb_tag_access_reg_t tag, const char *str);
    63 static void do_fast_data_access_protection_fault(istate_t *istate,
    64     tlb_tag_access_reg_t tag, const char *str);
     57static void dtlb_pte_copy(pte_t *, index_t, bool);
     58static void itlb_pte_copy(pte_t *, index_t);
     59static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
     60static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
     61    const char *);
     62static void do_fast_data_access_protection_fault(istate_t *,
     63    tlb_tag_access_reg_t, const char *);
    6564
    6665char *context_encoding[] = {
     
    8786/** Insert privileged mapping into DMMU TLB.
    8887 *
    89  * @param page Virtual page address.
    90  * @param frame Physical frame address.
    91  * @param pagesize Page size.
    92  * @param locked True for permanent mappings, false otherwise.
    93  * @param cacheable True if the mapping is cacheable, false otherwise.
     88 * @param page          Virtual page address.
     89 * @param frame         Physical frame address.
     90 * @param pagesize      Page size.
     91 * @param locked        True for permanent mappings, false otherwise.
     92 * @param cacheable     True if the mapping is cacheable, false otherwise.
    9493 */
    9594void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
     
    104103        fr.address = frame;
    105104
    106         tag.value = ASID_KERNEL;
     105        tag.context = ASID_KERNEL;
    107106        tag.vpn = pg.vpn;
    108107
     
    127126/** Copy PTE to TLB.
    128127 *
    129  * @param t     Page Table Entry to be copied.
    130  * @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
    131  * @param ro    If true, the entry will be created read-only, regardless of its
    132  *              w field.
     128 * @param t             Page Table Entry to be copied.
     129 * @param index         Zero if lower 8K-subpage, one if higher 8K-subpage.
     130 * @param ro            If true, the entry will be created read-only, regardless
     131 *                      of its w field.
    133132 */
    134133void dtlb_pte_copy(pte_t *t, index_t index, bool ro)
     
    166165/** Copy PTE to ITLB.
    167166 *
    168  * @param t     Page Table Entry to be copied.
    169  * @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
     167 * @param t             Page Table Entry to be copied.
     168 * @param index         Zero if lower 8K-subpage, one if higher 8K-subpage.
    170169 */
    171170void itlb_pte_copy(pte_t *t, index_t index)
     
    236235 * low-level, assembly language part of the fast_data_access_mmu_miss handler.
    237236 *
    238  * @param tag Content of the TLB Tag Access register as it existed when the
    239  *    trap happened. This is to prevent confusion created by clobbered
    240  *    Tag Access register during a nested DTLB miss.
    241  * @param istate Interrupted state saved on the stack.
     237 * @param tag           Content of the TLB Tag Access register as it existed
     238 *                      when the trap happened. This is to prevent confusion
     239 *                      created by clobbered Tag Access register during a nested
     240 *                      DTLB miss.
     241 * @param istate        Interrupted state saved on the stack.
    242242 */
    243243void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
     
    288288/** DTLB protection fault handler.
    289289 *
    290  * @param tag Content of the TLB Tag Access register as it existed when the
    291  *    trap happened. This is to prevent confusion created by clobbered
    292  *    Tag Access register during a nested DTLB miss.
    293  * @param istate Interrupted state saved on the stack.
     290 * @param tag           Content of the TLB Tag Access register as it existed
     291 *                      when the trap happened. This is to prevent confusion
     292 *                      created by clobbered Tag Access register during a nested
     293 *                      DTLB miss.
     294 * @param istate        Interrupted state saved on the stack.
    294295 */
    295296void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
     
    332333}
    333334
     335/** Print TLB entry (for debugging purposes).
     336 *
     337 * The diag field has been left out in order to make this function more generic
     338 * (there is no diag field in US3 architeture).
     339 *
     340 * @param i             TLB entry number
     341 * @param t             TLB entry tag
     342 * @param d             TLB entry data
     343 */
     344static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
     345{
     346        printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
     347            "ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
     348            "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
     349            t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
     350            d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
     351}
     352
     353#if defined (US)
     354
    334355/** Print contents of both TLBs. */
    335356void tlb_print(void)
     
    343364                d.value = itlb_data_access_read(i);
    344365                t.value = itlb_tag_read_read(i);
    345 
    346                 printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
    347                     "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
    348                     "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
    349                     t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
    350                     d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
     366                print_tlb_entry(i, t, d);
    351367        }
    352368
     
    355371                d.value = dtlb_data_access_read(i);
    356372                t.value = dtlb_tag_read_read(i);
    357                
    358                 printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
    359                     "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
    360                     "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
    361                     t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
    362                     d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
    363         }
    364 
    365 }
     373                print_tlb_entry(i, t, d);
     374        }
     375}
     376
     377#elif defined (US3)
     378
     379/** Print contents of all TLBs. */
     380void tlb_print(void)
     381{
     382        int i;
     383        tlb_data_t d;
     384        tlb_tag_read_reg_t t;
     385       
     386        printf("TLB_ISMALL contents:\n");
     387        for (i = 0; i < tlb_ismall_size(); i++) {
     388                d.value = dtlb_data_access_read(TLB_ISMALL, i);
     389                t.value = dtlb_tag_read_read(TLB_ISMALL, i);
     390                print_tlb_entry(i, t, d);
     391        }
     392       
     393        printf("TLB_IBIG contents:\n");
     394        for (i = 0; i < tlb_ibig_size(); i++) {
     395                d.value = dtlb_data_access_read(TLB_IBIG, i);
     396                t.value = dtlb_tag_read_read(TLB_IBIG, i);
     397                print_tlb_entry(i, t, d);
     398        }
     399       
     400        printf("TLB_DSMALL contents:\n");
     401        for (i = 0; i < tlb_dsmall_size(); i++) {
     402                d.value = dtlb_data_access_read(TLB_DSMALL, i);
     403                t.value = dtlb_tag_read_read(TLB_DSMALL, i);
     404                print_tlb_entry(i, t, d);
     405        }
     406       
     407        printf("TLB_DBIG_1 contents:\n");
     408        for (i = 0; i < tlb_dbig_size(); i++) {
     409                d.value = dtlb_data_access_read(TLB_DBIG_0, i);
     410                t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
     411                print_tlb_entry(i, t, d);
     412        }
     413       
     414        printf("TLB_DBIG_2 contents:\n");
     415        for (i = 0; i < tlb_dbig_size(); i++) {
     416                d.value = dtlb_data_access_read(TLB_DBIG_1, i);
     417                t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
     418                print_tlb_entry(i, t, d);
     419        }
     420}
     421
     422#endif
    366423
    367424void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
     
    412469        sfar = dtlb_sfar_read();
    413470       
     471#if defined (US)
    414472        printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
    415473            "fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
    416474            sfsr.ow, sfsr.fv);
     475#elif defined (US3)
     476        printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
     477            "w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
     478            sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
     479#endif
     480           
    417481        printf("DTLB SFAR: address=%p\n", sfar);
    418482       
    419483        dtlb_sfsr_write(0);
    420484}
     485
     486#if defined (US3)
     487/** Invalidates given TLB entry if and only if it is non-locked or global.
     488 *
     489 * @param tlb           TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1,
     490 *                      TLB_ISMALL, TLB_IBIG).
     491 * @param entry         Entry index within the given TLB.
     492 */
     493static void tlb_invalidate_entry(int tlb, index_t entry)
     494{
     495        tlb_data_t d;
     496        tlb_tag_read_reg_t t;
     497       
     498        if (tlb == TLB_DSMALL || tlb == TLB_DBIG_0 || tlb == TLB_DBIG_1) {
     499                d.value = dtlb_data_access_read(tlb, entry);
     500                if (!d.l || d.g) {
     501                        t.value = dtlb_tag_read_read(tlb, entry);
     502                        d.v = false;
     503                        dtlb_tag_access_write(t.value);
     504                        dtlb_data_access_write(tlb, entry, d.value);
     505                }
     506        } else if (tlb == TLB_ISMALL || tlb == TLB_IBIG) {
     507                d.value = itlb_data_access_read(tlb, entry);
     508                if (!d.l || d.g) {
     509                        t.value = itlb_tag_read_read(tlb, entry);
     510                        d.v = false;
     511                        itlb_tag_access_write(t.value);
     512                        itlb_data_access_write(tlb, entry, d.value);
     513                }
     514        }
     515}
     516#endif
    421517
    422518/** Invalidate all unlocked ITLB and DTLB entries. */
     
    424520{
    425521        int i;
    426         tlb_data_t d;
    427         tlb_tag_read_reg_t t;
    428 
     522       
    429523        /*
    430524         * Walk all ITLB and DTLB entries and remove all unlocked mappings.
    431525         *
    432526         * The kernel doesn't use global mappings so any locked global mappings
    433          * found  must have been created by someone else. Their only purpose now
     527         * found must have been created by someone else. Their only purpose now
    434528         * is to collide with proper mappings. Invalidate immediately. It should
    435529         * be safe to invalidate them as late as now.
    436530         */
     531
     532#if defined (US)
     533        tlb_data_t d;
     534        tlb_tag_read_reg_t t;
    437535
    438536        for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
     
    445543                }
    446544        }
    447        
     545
    448546        for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
    449547                d.value = dtlb_data_access_read(i);
     
    455553                }
    456554        }
    457        
     555
     556#elif defined (US3)
     557
     558        for (i = 0; i < tlb_ismall_size(); i++)
     559                tlb_invalidate_entry(TLB_ISMALL, i);
     560        for (i = 0; i < tlb_ibig_size(); i++)
     561                tlb_invalidate_entry(TLB_IBIG, i);
     562        for (i = 0; i < tlb_dsmall_size(); i++)
     563                tlb_invalidate_entry(TLB_DSMALL, i);
     564        for (i = 0; i < tlb_dbig_size(); i++)
     565                tlb_invalidate_entry(TLB_DBIG_0, i);
     566        for (i = 0; i < tlb_dbig_size(); i++)
     567                tlb_invalidate_entry(TLB_DBIG_1, i);
     568#endif
     569
    458570}
    459571
     
    485597 * address space.
    486598 *
    487  * @param asid Address Space ID.
    488  * @param page First page which to sweep out from ITLB and DTLB.
    489  * @param cnt Number of ITLB and DTLB entries to invalidate.
     599 * @param asid          Address Space ID.
     600 * @param page          First page which to sweep out from ITLB and DTLB.
     601 * @param cnt           Number of ITLB and DTLB entries to invalidate.
    490602 */
    491603void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
  • kernel/arch/sparc64/src/mm/tsb.c

    r0258e67 r965dc18  
    113113        tsb->data.size = PAGESIZE_8K;
    114114        tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
    115         tsb->data.cp = t->c;
    116         tsb->data.p = t->k;             /* p as privileged */
    117         tsb->data.v = t->p;
     115        tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
     116        tsb->data.p = t->k;     /* p as privileged, k as kernel */
     117        tsb->data.v = t->p;     /* v as valid, p as present */
    118118       
    119119        write_barrier();
     
    174174/** @}
    175175 */
     176
  • kernel/arch/sparc64/src/smp/ipi.c

    r0258e67 r965dc18  
    4747#include <panic.h>
    4848
     49/** Set the contents of the outgoing interrupt vector data.
     50 *
     51 * The first data item (data 0) will be set to the value of func, the
     52 * rest of the vector will contain zeros.
     53 *
     54 * This is a helper function used from within the cross_call function.
     55 *
     56 * @param func value the first data item of the vector will be set to
     57 */
     58static inline void set_intr_w_data(void (* func)(void))
     59{
     60#if defined (US)
     61        asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_0, (uintptr_t) func);
     62        asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_1, 0);
     63        asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_2, 0);
     64#elif defined (US3)
     65        asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_0, (uintptr_t) func);
     66        asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_1, 0);
     67        asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_2, 0);
     68        asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_3, 0);
     69        asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_4, 0);
     70        asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_5, 0);
     71        asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_6, 0);
     72        asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_7, 0);
     73#endif
     74}
     75
    4976/** Invoke function on another processor.
    5077 *
     
    74101                panic("Interrupt Dispatch Status busy bit set\n");
    75102       
     103        ASSERT(!(pstate_read() & PSTATE_IE_BIT));
     104       
    76105        do {
    77                 asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_0,
    78                     (uintptr_t) func);
    79                 asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_1, 0);
    80                 asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_2, 0);
    81                 asi_u64_write(ASI_UDB_INTR_W,
     106                set_intr_w_data(func);
     107                asi_u64_write(ASI_INTR_W,
    82108                    (mid << INTR_VEC_DISPATCH_MID_SHIFT) |
    83                     ASI_UDB_INTR_W_DISPATCH, 0);
     109                    VA_INTR_W_DISPATCH, 0);
    84110       
    85111                membar();
  • kernel/arch/sparc64/src/smp/smp.c

    r0258e67 r965dc18  
    3636#include <genarch/ofw/ofw_tree.h>
    3737#include <cpu.h>
     38#include <arch/cpu_family.h>
    3839#include <arch/cpu.h>
    3940#include <arch.h>
     
    4445#include <synch/waitq.h>
    4546#include <print.h>
     47#include <arch/cpu_node.h>
    4648
    4749/**
     
    6264        count_t cnt = 0;
    6365       
    64         node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
    65         while (node) {
    66                 cnt++;
    67                 node = ofw_tree_find_peer_by_device_type(node, "cpu");
     66        if (is_us() || is_us_iii()) {
     67                node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
     68                while (node) {
     69                        cnt++;
     70                        node = ofw_tree_find_peer_by_device_type(node, "cpu");
     71                }
     72        } else if (is_us_iv()) {
     73                node = ofw_tree_find_child(cpus_parent(), "cmp");
     74                while (node) {
     75                        cnt += 2;
     76                        node = ofw_tree_find_peer_by_name(node, "cmp");
     77                }
    6878        }
    6979       
    7080        config.cpu_count = max(1, cnt);
     81}
     82
     83/**
     84 * Wakes up the CPU which is represented by the "node" OFW tree node.
     85 * If "node" represents the current CPU, calling the function has
     86 * no effect.
     87 */
     88static void wakeup_cpu(ofw_tree_node_t *node)
     89{
     90        uint32_t mid;
     91        ofw_tree_property_t *prop;
     92               
     93        /* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */
     94        prop = ofw_tree_getprop(node, "upa-portid");
     95        if ((!prop) || (!prop->value))
     96                prop = ofw_tree_getprop(node, "portid");
     97        if ((!prop) || (!prop->value))
     98                prop = ofw_tree_getprop(node, "cpuid");
     99               
     100        if (!prop || prop->value == NULL)
     101                return;
     102               
     103        mid = *((uint32_t *) prop->value);
     104        if (CPU->arch.mid == mid)
     105                return;
     106
     107        waking_up_mid = mid;
     108               
     109        if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) ==
     110            ESYNCH_TIMEOUT)
     111                printf("%s: waiting for processor (mid = %" PRIu32
     112                    ") timed out\n", __func__, mid);
    71113}
    72114
     
    77119        int i;
    78120       
    79         node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
    80         for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) {
    81                 uint32_t mid;
    82                 ofw_tree_property_t *prop;
    83                
    84                 prop = ofw_tree_getprop(node, "upa-portid");
    85                 if (!prop || !prop->value)
    86                         continue;
    87                
    88                 mid = *((uint32_t *) prop->value);
    89                 if (CPU->arch.mid == mid) {
    90                         /*
    91                          * Skip the current CPU.
    92                          */
    93                         continue;
     121        if (is_us() || is_us_iii()) {
     122                node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
     123                for (i = 0; node;
     124                     node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++)
     125                        wakeup_cpu(node);
     126        } else if (is_us_iv()) {
     127                node = ofw_tree_find_child(cpus_parent(), "cmp");
     128                while (node) {
     129                        wakeup_cpu(ofw_tree_find_child(node, "cpu@0"));
     130                        wakeup_cpu(ofw_tree_find_child(node, "cpu@1"));
     131                        node = ofw_tree_find_peer_by_name(node, "cmp");
    94132                }
    95 
    96                 /*
    97                  * Processor with ID == mid can proceed with its initialization.
    98                  */
    99                 waking_up_mid = mid;
    100                
    101                 if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT)
    102                         printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n",
    103                             __func__, mid);
    104133        }
    105134}
  • kernel/arch/sparc64/src/sparc64.c

    r0258e67 r965dc18  
    8787                 */
    8888                irq_init(1 << 11, 128);
    89                
     89
    9090                standalone_sparc64_console_init();
    9191        }
  • kernel/arch/sparc64/src/start.S

    r0258e67 r965dc18  
    2828
    2929#include <arch/arch.h>
     30#include <arch/cpu.h>
    3031#include <arch/regdef.h>
    3132#include <arch/boot/boot.h>
     
    4647
    4748#define BSP_FLAG        1
     49
     50/*
     51 * 2^PHYSMEM_ADDR_SIZE is the size of the physical address space on
     52 * a given processor.
     53 */
     54#if defined (US)
     55    #define PHYSMEM_ADDR_SIZE   41
     56#elif defined (US3)
     57    #define PHYSMEM_ADDR_SIZE   43
     58#endif
    4859
    4960/*
     
    6879        andn %o0, %l0, %l6                      ! l6 <= start of physical memory
    6980
    70         ! Get bits 40:13 of physmem_base.
     81        ! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base.
    7182        srlx %l6, 13, %l5
    72         sllx %l5, 13 + (63 - 40), %l5
    73         srlx %l5, 63 - 40, %l5                  ! l5 <= physmem_base[40:13]
     83       
     84        ! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13]
     85        sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5
     86        srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5     
    7487       
    7588        /*
     
    8497        wrpr %g0, NWINDOWS - 1, %cleanwin       ! prevent needless clean_window
    8598                                                ! traps for kernel
     99                                               
     100        wrpr %g0, 0, %wstate                    ! use default spill/fill trap
    86101
    87102        wrpr %g0, 0, %tl                        ! TL = 0, primary context
     
    245260        /*
    246261         * Precompute kernel 8K TLB data template.
    247          * %l5 contains starting physical address bits [40:13]
     262         * %l5 contains starting physical address
     263         * bits [(PHYSMEM_ADDR_SIZE - 1):13]
    248264         */
    249265        sethi %hi(kernel_8k_tlb_data_template), %l4
     
    283299
    284300
     3011:
     302#ifdef CONFIG_SMP
     303        /*
     304         * Determine the width of the MID and save its mask to %g3. The width
     305         * is
     306         *      * 5 for US and US-IIIi,
     307         *      * 10 for US3 except US-IIIi.
     308         */
     309#if defined(US)
     310        mov 0x1f, %g3
     311#elif defined(US3)
     312        mov 0x3ff, %g3
     313        rdpr %ver, %g2
     314        sllx %g2, 16, %g2
     315        srlx %g2, 48, %g2
     316        cmp %g2, IMPL_ULTRASPARCIII_I
     317        move %xcc, 0x1f, %g3
     318#endif
     319
    285320        /*
    286321         * Read MID from the processor.
    287322         */
    288 1:
    289         ldxa [%g0] ASI_UPA_CONFIG, %g1
    290         srlx %g1, UPA_CONFIG_MID_SHIFT, %g1
    291         and %g1, UPA_CONFIG_MID_MASK, %g1
    292 
    293 #ifdef CONFIG_SMP
     323        ldxa [%g0] ASI_ICBUS_CONFIG, %g1
     324        srlx %g1, ICBUS_CONFIG_MID_SHIFT, %g1
     325        and %g1, %g3, %g1
     326
    294327        /*
    295328         * Active loop for APs until the BSP picks them up. A processor cannot
  • kernel/arch/sparc64/src/trap/interrupt.c

    r0258e67 r965dc18  
    6868void interrupt(int n, istate_t *istate)
    6969{
     70        uint64_t status;
    7071        uint64_t intrcv;
    7172        uint64_t data0;
     73        status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
     74        if (status & (!INTR_DISPATCH_STATUS_BUSY))
     75                panic("Interrupt Dispatch Status busy bit not set\n");
    7276
    7377        intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
    74         data0 = asi_u64_read(ASI_UDB_INTR_R, ASI_UDB_INTR_R_DATA_0);
     78#if defined (US)
     79        data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0);
     80#elif defined (US3)
     81        data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0);
     82#endif
    7583
    7684        irq_t *irq = irq_dispatch_and_lock(data0);
  • kernel/genarch/include/fb/fb.h

    r0258e67 r965dc18  
    3939#include <synch/spinlock.h>
    4040
     41/**
     42 * Properties of the framebuffer device.
     43 */
     44typedef struct fb_properties {
     45        /** Physical address of the framebuffer device. */
     46        uintptr_t addr;
     47
     48        /**
     49         * Address where the first (top left) pixel is mapped,
     50         * relative to "addr".
     51         */
     52        unsigned int offset;   
     53
     54        /** Screen width in pixels. */
     55        unsigned int x;
     56
     57        /** Screen height in pixels. */
     58        unsigned int y;
     59
     60        /** Bytes per one scanline. */
     61        unsigned int scan;
     62
     63        /** Color model. */
     64        unsigned int visual;
     65} fb_properties_t;
     66
    4167SPINLOCK_EXTERN(fb_lock);
    42 void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int scan, unsigned int visual);
     68void fb_init(fb_properties_t *props);
    4369
    4470#endif
  • kernel/genarch/include/fb/visuals.h

    r0258e67 r965dc18  
    4545
    4646#define VISUAL_BGR_0_8_8_8      6
     47#define VISUAL_SB1500_PALETTE   7
    4748
    4849#endif
  • kernel/genarch/include/ofw/ofw_tree.h

    r0258e67 r965dc18  
    173173extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *,
    174174    const char *);
     175extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node,
     176    const char *name);
    175177extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *,
    176178    uint32_t);
  • kernel/genarch/src/fb/fb.c

    r0258e67 r965dc18  
    190190        *((uint8_t *) dst) = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 |
    191191            BLUE(rgb, 3);
     192}
     193
     194static void sb1500rgb_byte8(void *dst, int rgb)
     195{
     196        if (RED(rgb, 1) && GREEN(rgb, 1) && BLUE(rgb, 1))
     197                *((uint8_t *) dst) = 255;
     198        else if (RED(rgb, 1) && GREEN(rgb, 1))
     199                *((uint8_t *) dst) = 150;
     200        else if (GREEN(rgb, 1) && BLUE(rgb, 1))
     201                *((uint8_t *) dst) = 47;
     202        else if (RED(rgb, 1) && BLUE(rgb, 1))
     203                *((uint8_t *) dst) = 48;
     204        else if (RED(rgb, 1))
     205                *((uint8_t *) dst) = 32;
     206        else if (GREEN(rgb, 1))
     207                *((uint8_t *) dst) = 47;
     208        else if (BLUE(rgb, 1))
     209                *((uint8_t *) dst) = 2;
     210        else
     211                *((uint8_t *) dst) = 1;
    192212}
    193213
     
    437457/** Initialize framebuffer as a chardev output device
    438458 *
    439  * @param addr   Physical address of the framebuffer
    440  * @param x      Screen width in pixels
    441  * @param y      Screen height in pixels
    442  * @param scan   Bytes per one scanline
    443  * @param visual Color model
    444  *
    445  */
    446 void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int scan,
    447     unsigned int visual)
    448 {
    449         switch (visual) {
     459 * @param props         Properties of the framebuffer device.
     460 */
     461void fb_init(fb_properties_t *props)
     462{
     463        switch (props->visual) {
    450464        case VISUAL_INDIRECT_8:
    451465                rgb2scr = rgb_byte8;
     
    453467                pixelbytes = 1;
    454468                break;
     469        case VISUAL_SB1500_PALETTE:
     470                rgb2scr = sb1500rgb_byte8;
     471                scr2rgb = byte8_rgb;
     472                pixelbytes = 1;
     473                break;
    455474        case VISUAL_RGB_5_5_5:
    456475                rgb2scr = rgb_byte555;
     
    487506        }
    488507       
    489         unsigned int fbsize = scan * y;
     508        unsigned int fbsize = props->scan * props->y + props->offset;
    490509       
    491510        /* Map the framebuffer */
    492         fbaddress = (uint8_t *) hw_map((uintptr_t) addr, fbsize);
    493        
    494         xres = x;
    495         yres = y;
    496         scanline = scan;
    497        
    498         rows = y / FONT_SCANLINES;
    499         columns = x / COL_WIDTH;
    500 
    501         fb_parea.pbase = (uintptr_t) addr;
     511        fbaddress = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
     512        fbaddress += props->offset;
     513       
     514        xres = props->x;
     515        yres = props->y;
     516        scanline = props->scan;
     517       
     518        rows = props->y / FONT_SCANLINES;
     519        columns = props->x / COL_WIDTH;
     520
     521        fb_parea.pbase = (uintptr_t) props->addr;
    502522        fb_parea.vbase = (uintptr_t) fbaddress;
    503523        fb_parea.frames = SIZE2FRAMES(fbsize);
     
    509529        sysinfo_set_item_val("fb.width", NULL, xres);
    510530        sysinfo_set_item_val("fb.height", NULL, yres);
    511         sysinfo_set_item_val("fb.scanline", NULL, scan);
    512         sysinfo_set_item_val("fb.visual", NULL, visual);
    513         sysinfo_set_item_val("fb.address.physical", NULL, addr);
     531        sysinfo_set_item_val("fb.scanline", NULL, props->scan);
     532        sysinfo_set_item_val("fb.visual", NULL, props->visual);
     533        sysinfo_set_item_val("fb.address.physical", NULL, props->addr);
    514534        sysinfo_set_item_val("fb.invert-colors", NULL, invert_colors);
    515535
     
    525545        if (!blankline)
    526546                panic("Failed to allocate blank line for framebuffer.");
     547        unsigned int x, y;
    527548        for (y = 0; y < FONT_SCANLINES; y++)
    528549                for (x = 0; x < xres; x++)
  • kernel/genarch/src/ofw/ofw_tree.c

    r0258e67 r965dc18  
    5555/** Get OpenFirmware node property.
    5656 *
    57  * @param node Node in which to lookup the property.
    58  * @param name Name of the property.
    59  *
    60  * @return Pointer to the property structure or NULL if no such property.
    61  */
    62 ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name)
     57 * @param node          Node in which to lookup the property.
     58 * @param name          Name of the property.
     59 *
     60 * @return              Pointer to the property structure or NULL if no such
     61 *                      property.
     62 */
     63ofw_tree_property_t *
     64ofw_tree_getprop(const ofw_tree_node_t *node, const char *name)
    6365{
    6466        unsigned int i;
     
    7476/** Return value of the 'name' property.
    7577 *
    76  * @param node Node of interest.
    77  *
    78  * @return Value of the 'name' property belonging to the node.
     78 * @param node          Node of interest.
     79 *
     80 * @return              Value of the 'name' property belonging to the node.
    7981 */
    8082const char *ofw_tree_node_name(const ofw_tree_node_t *node)
     
    9496/** Lookup child of given name.
    9597 *
    96  * @param node Node whose child is being looked up.
    97  * @param name Name of the child being looked up.
    98  *
    99  * @return NULL if there is no such child or pointer to the matching child node.
     98 * @param node          Node whose child is being looked up.
     99 * @param name          Name of the child being looked up.
     100 *
     101 * @return              NULL if there is no such child or pointer to the
     102 *                      matching child node.
    100103 */
    101104ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name)
     
    128131/** Lookup first child of given device type.
    129132 *
    130  * @param node Node whose child is being looked up.
    131  * @param name Device type of the child being looked up.
    132  *
    133  * @return NULL if there is no such child or pointer to the matching child node.
    134  */
    135 ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name)
     133 * @param node          Node whose child is being looked up.
     134 * @param name          Device type of the child being looked up.
     135 *
     136 * @return              NULL if there is no such child or pointer to the
     137 *                      matching child node.
     138 */
     139ofw_tree_node_t *
     140ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name)
    136141{
    137142        ofw_tree_node_t *cur;
     
    154159 * are looked up iteratively to avoid stack overflow.
    155160 *
    156  * @param root Root of the searched subtree.
    157  * @param handle OpenFirmware handle.
    158  *
    159  * @return NULL if there is no such node or pointer to the matching node.
    160  */
    161 ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle)
     161 * @param root          Root of the searched subtree.
     162 * @param handle        OpenFirmware handle.
     163 *
     164 * @return              NULL if there is no such node or pointer to the matching
     165 *                      node.
     166 */
     167ofw_tree_node_t *
     168ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle)
    162169{
    163170        ofw_tree_node_t *cur;
     
    181188/** Lookup first peer of given device type.
    182189 *
    183  * @param node Node whose peer is being looked up.
    184  * @param name Device type of the child being looked up.
    185  *
    186  * @return NULL if there is no such child or pointer to the matching child node.
    187  */
    188 ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name)
     190 * @param node          Node whose peer is being looked up.
     191 * @param name          Device type of the child being looked up.
     192 *
     193 * @return              NULL if there is no such child or pointer to the
     194 *                      matching child node.
     195 */
     196ofw_tree_node_t *
     197ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name)
    189198{
    190199        ofw_tree_node_t *cur;
     
    203212
    204213
     214/** Lookup first peer of given name.
     215 *
     216 * @param node          Node whose peer is being looked up.
     217 * @param name          Name of the child being looked up.
     218 *
     219 * @return              NULL if there is no such peer or pointer to the matching
     220 *                      peer node.
     221 */
     222ofw_tree_node_t *
     223ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name)
     224{
     225        ofw_tree_node_t *cur;
     226        ofw_tree_property_t *prop;
     227       
     228        for (cur = node->peer; cur; cur = cur->peer) {
     229                prop = ofw_tree_getprop(cur, "name");
     230                if (!prop || !prop->value)
     231                        continue;
     232                if (strcmp(prop->value, name) == 0)
     233                        return cur;
     234        }
     235                       
     236        return NULL;
     237}
     238
    205239/** Lookup OpenFirmware node by its path.
    206240 *
    207  * @param path Path to the node.
    208  *
    209  * @return NULL if there is no such node or pointer to the leaf node.
     241 * @param path          Path to the node.
     242 *
     243 * @return              NULL if there is no such node or pointer to the leaf
     244 *                      node.
    210245 */
    211246ofw_tree_node_t *ofw_tree_lookup(const char *path)
    212247{
    213         char buf[NAME_BUF_LEN+1];
     248        char buf[NAME_BUF_LEN + 1];
    214249        ofw_tree_node_t *node = ofw_root;
    215250        index_t i, j;
     
    237272 * iteratively in order to avoid stack overflow.
    238273 *
    239  * @param node Root of the subtree.
    240  * @param path Current path, NULL for the very root of the entire tree.
     274 * @param node          Root of the subtree.
     275 * @param path          Current path, NULL for the very root of the entire tree.
    241276 */
    242277static void ofw_tree_node_print(const ofw_tree_node_t *node, const char *path)
  • kernel/kernel.config

    r0258e67 r965dc18  
    7777! [ARCH=amd64] MACHINE (choice)
    7878
     79# CPU type
     80@ "us" UltraSPARC I-II subarchitecture
     81@ "us3" UltraSPARC III-IV subarchitecture
     82! [ARCH=sparc64] MACHINE (choice)
     83
    7984# Machine type
    8085@ "msim" MSIM Simulator
     
    139144! [ARCH=sparc64] CONFIG_Z8530 (y/n)
    140145
    141 # Support for NS16550 serial port (On IA64 as a console instead legacy keyboard)
    142 ! [ARCH=sparc64] CONFIG_NS16550 (y/n)
     146# Support for NS16550 serial port
     147! [ARCH=sparc64|(ARCH=ia64&MACHINE!=ski)] CONFIG_NS16550 (n/y)
    143148
    144 # Support for NS16550 serial port (On IA64 as a console instead legacy keyboard)
    145 ! [ARCH=ia64&MACHINE!=ski] CONFIG_NS16550 (n/y)
     149# Support for Serengeti console
     150! [ARCH=sparc64] CONFIG_SGCN (y/n)
    146151
    147 # IOSapic on default address support (including legacy IRQ)
     152# IOSapic on default address support
    148153! [ARCH=ia64&MACHINE!=ski] CONFIG_IOSAPIC (y/n)
    149154
Note: See TracChangeset for help on using the changeset viewer.