Changeset 45b26dad in mainline


Ignore:
Timestamp:
2006-09-26T12:59:28Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b44939b
Parents:
6ff1f1e
Message:

sparc64 work:

  • Loader now starts all processors.
  • Kernel halts all but the bootstrup processor for now.
  • Read clock-frequency from the respective processor node in the device tree
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/sparc64/loader/asm.S

    r6ff1f1e r45b26dad  
    101101        mov %o1, %o0
    102102        mov %o2, %o1
     103        mov %o3, %o2
    103104        jmp %l1                         ! jump to kernel
    104105        nop
  • boot/arch/sparc64/loader/asm.h

    r6ff1f1e r45b26dad  
    3636
    3737extern void halt(void);
    38 extern void jump_to_kernel(void *entry, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn));
     38extern void jump_to_kernel(void *entry, int bsp, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn));
    3939
    4040#endif
  • boot/arch/sparc64/loader/main.c

    r6ff1f1e r45b26dad  
    3737#include <align.h>
    3838
    39 #define KERNEL_VIRTUAL_ADDRESS 0x400000
    40 
    4139bootinfo_t bootinfo;
    4240
     
    5856        }
    5957       
    60         if (!ofw_cpu(&bootinfo.cpu))
    61                 printf("Error: unable to get cpu properties\n");
    62 
    63         printf("\nDevice info\n");
    64         printf(" cpu: %dMHz\n", bootinfo.cpu.clock_frequency/1000000);
     58        printf("\nSystem info\n");
    6559        printf(" memory: %dM\n", bootinfo.memmap.total>>20);
    6660
     
    9791        printf("done.\n");
    9892
     93        printf("\nChecking for secondary processors...");
     94        if (!ofw_cpu())
     95                printf("Error: unable to get cpu properties\n");
     96        printf("done.\n");
     97
    9998        printf("\nBooting the kernel...\n");
    100         jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo, sizeof(bootinfo));
     99        jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, 1, &bootinfo, sizeof(bootinfo));
    101100}
  • boot/arch/sparc64/loader/main.h

    r6ff1f1e r45b26dad  
    3535#include <types.h>
    3636
     37#define KERNEL_VIRTUAL_ADDRESS 0x400000
     38
    3739#define TASKMAP_MAX_RECORDS 32
    3840
     
    4850
    4951typedef struct {
    50         uint32_t clock_frequency;
    51 } cpu_t;
    52 
    53 typedef struct {
    5452        taskmap_t taskmap;
    5553        memmap_t memmap;
    56         cpu_t cpu;
    5754        ballocs_t ballocs;
    5855        ofw_tree_node_t *ofw_root;
  • boot/arch/sparc64/loader/ofwarch.c

    r6ff1f1e r45b26dad  
    5454}
    5555
    56 int ofw_cpu(cpu_t *cpu)
     56
     57#define ASI_UPA_CONFIG          0x4a
     58#define UPA_CONFIG_MID_SHIFT    17
     59#define UPA_CONFIG_MID_MASK     0x1f
     60
     61int ofw_cpu(void)
    5762{
    5863        char type_name[BUF_SIZE];
     
    6267        if (node == 0 || node == -1) {
    6368                printf("Could not find any child nodes of the root node.\n");
    64                 return;
     69                return 0;
    6570        }
     71       
     72        uint64_t current_mid;
     73       
     74        __asm__ volatile ("ldxa [%1] %2, %0\n" : "=r" (current_mid) : "r" (0), "i" (ASI_UPA_CONFIG));
     75        current_mid >>= UPA_CONFIG_MID_SHIFT;
     76        current_mid &= UPA_CONFIG_MID_MASK;
    6677       
    6778        for (; node != 0 && node != -1; node = ofw_get_peer_node(node)) {
    6879                if (ofw_get_property(node, "device_type", type_name, sizeof(type_name)) > 0) {
    6980                        if (strcmp(type_name, "cpu") == 0) {
    70                                 uint32_t mhz;
     81                                uint32_t mid;
    7182                               
    72                                 if (ofw_get_property(node, "clock-frequency", &mhz, sizeof(mhz)) <= 0)
     83                                if (ofw_get_property(node, "upa-portid", &mid, sizeof(mid)) <= 0)
    7384                                        continue;
    7485                                       
    75                                 cpu->clock_frequency = mhz;
    76                                 return 1;
     86                                if (current_mid != mid) {
     87                                        /*
     88                                         * Start secondary processor.
     89                                         */
     90                                        (void) ofw_call("SUNW,start-cpu", 3, 1, NULL, node, KERNEL_VIRTUAL_ADDRESS, 0);
     91                                }
    7792                        }
    7893                }
    79         };
     94        }
    8095
    81         return 0;
     96        return 1;
    8297}
  • boot/arch/sparc64/loader/ofwarch.h

    r6ff1f1e r45b26dad  
    3535#define OFW_SIZE_CELLS          2
    3636
    37 extern int bpp2align[];
    38 
    39 extern int ofw_cpu(cpu_t *cpu);
     37extern int ofw_cpu(void);
    4038
    4139#endif
  • boot/genarch/ofw.c

    r6ff1f1e r45b26dad  
    8484 * @return Return value returned by the client interface.
    8585 */
    86 static unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...)
     86unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...)
    8787{
    8888        va_list list;
  • boot/genarch/ofw.h

    r6ff1f1e r45b26dad  
    9191extern uintptr_t ofw_cif;
    9292
    93 
    9493extern phandle ofw_chosen;
    9594extern ihandle ofw_stdout;
     
    114113
    115114extern int ofw(ofw_args_t *arg);
     115extern unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...);
    116116extern unsigned int ofw_get_address_cells(const phandle device);
    117117extern unsigned int ofw_get_size_cells(const phandle device);
  • kernel/arch/sparc64/include/arch.h

    r6ff1f1e r45b26dad  
    3838#define KERN_sparc64_ARCH_H_
    3939
    40 #define ASI_AIUP        0x10            /** Access to primary context with user privileges. */
    41 #define ASI_AIUS        0x11            /** Access to secondary context with user privileges. */
    42 
     40#define ASI_AIUP                0x10    /** Access to primary context with user privileges. */
     41#define ASI_AIUS                0x11    /** Access to secondary context with user privileges. */
    4342#define ASI_NUCLEUS_QUAD_LDD    0x24    /** ASI for 16-byte atomic loads. */
     43#define ASI_UPA_CONFIG          0x4a    /** ASI of the UPA_CONFIG register. */
    4444
    4545#define NWINDOW         8               /** Number of register window sets. */
  • kernel/arch/sparc64/include/asm.h

    r6ff1f1e r45b26dad  
    359359}
    360360
     361/** Read UPA_CONFIG register.
     362 *
     363 * @return Value of the UPA_CONFIG register.
     364 */
     365static inline uint64_t upa_config_read(void)
     366{
     367        return asi_u64_read(ASI_UPA_CONFIG, 0);
     368}
     369
    361370extern void cpu_halt(void);
    362371extern void cpu_sleep(void);
  • kernel/arch/sparc64/include/boot/boot.h

    r6ff1f1e r45b26dad  
    7171} memmap_t;
    7272
    73 typedef struct {
    74         uint32_t clock_frequency;
    75 } processor_t;
    76 
    7773/** Bootinfo structure.
    7874 *
     
    8278        taskmap_t taskmap;
    8379        memmap_t memmap;
    84         processor_t processor;
    8580        ballocs_t ballocs;
    8681        ofw_tree_node_t *ofw_root;
  • kernel/arch/sparc64/include/register.h

    r6ff1f1e r45b26dad  
    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 */
     126union 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};
     135typedef union upa_config upa_config_t;
     136
    120137#endif
    121138
  • kernel/arch/sparc64/src/cpu/cpu.c

    r6ff1f1e r45b26dad  
    3636#include <cpu.h>
    3737#include <arch.h>
     38#include <print.h>
    3839#include <arch/register.h>
    39 #include <print.h>
    40 #include <arch/boot/boot.h>
     40#include <genarch/ofw/ofw_tree.h>
     41#include <arch/types.h>
     42#include <arch/drivers/tick.h>
    4143
     44/** Perform sparc64 specific initialization of the processor structure for the current processor. */
    4245void cpu_arch_init(void)
    4346{
    44         CPU->arch.clock_frequency = bootinfo.processor.clock_frequency;
     47        ofw_tree_node_t *node;
     48        uint32_t mid;
     49        uint32_t clock_frequency = 0;
     50        upa_config_t upa_config;
     51       
     52        upa_config.value = upa_config_read();
     53        node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
     54        while (node) {
     55                ofw_tree_property_t *prop;
     56               
     57                prop = ofw_tree_getprop(node, "upa-portid");
     58                if (prop && prop->value) {
     59                        mid = *((uint32_t *) prop->value);
     60                        if (mid == upa_config.mid) {
     61                                prop = ofw_tree_getprop(node, "clock-frequency");
     62                                if (prop && prop->value)
     63                                        clock_frequency = *((uint32_t *) prop->value);
     64                        }
     65                }
     66                node = ofw_tree_find_peer_by_device_type(node, "cpu");
     67        }
     68
     69        CPU->arch.clock_frequency = clock_frequency;
     70        tick_init();
    4571}
    4672
     73/** Read version information from the current processor. */
    4774void cpu_identify(void)
    4875{
     
    5077}
    5178
     79/** Print version information for a processor.
     80 *
     81 * @param m Processor structure of the CPU for which version information is to be printed.
     82 */
    5283void cpu_print_report(cpu_t *m)
    5384{
  • kernel/arch/sparc64/src/drivers/tick.c

    r6ff1f1e r45b26dad  
    5353        interrupt_register(14, "tick_int", tick_interrupt);
    5454        compare.int_dis = false;
    55         compare.tick_cmpr = bootinfo.processor.clock_frequency/HZ;
     55        compare.tick_cmpr = CPU->arch.clock_frequency/HZ;
    5656        tick_compare_write(compare.value);
    5757        tick_write(0);
  • kernel/arch/sparc64/src/sparc64.c

    r6ff1f1e r45b26dad  
    3838#include <arch/trap/trap.h>
    3939#include <arch/console.h>
    40 #include <arch/drivers/tick.h>
    4140#include <proc/thread.h>
    4241#include <console/console.h>
     
    7372{
    7473        trap_init();
    75         tick_init();
    7674}
    7775
  • kernel/arch/sparc64/src/start.S

    r6ff1f1e r45b26dad  
    4444 *
    4545 * The registers are expected to be in this state:
    46  * - %o0 bootinfo structure address
    47  * - %o1 bootinfo structure size
     46 * - %o0 non-zero for the bootstrup processor, zero for application/secondary processors
     47 * - %o1 bootinfo structure address
     48 * - %o2 bootinfo structure size
    4849 *
    4950 * Moreover, we depend on boot having established the
     
    5657.global kernel_image_start
    5758kernel_image_start:
     59        brz %o0, kernel_image_start             ! block secondary processors
     60        nop
    5861
    5962        /*
     
    7376         * to the kernel bootinfo structure.
    7477         */
    75         mov %o1, %o2
    76         mov %o0, %o1
    7778        sethi %hi(bootinfo), %o0
    7879        call memcpy
  • kernel/genarch/include/ofw/ofw_tree.h

    r6ff1f1e r45b26dad  
    129129extern ofw_tree_node_t *ofw_tree_lookup(const char *path);
    130130extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name);
     131extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name);
     132extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *device_type);
     133extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *device_type);
    131134
    132135extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uintptr_t *pa);
  • kernel/genarch/src/ofw/ofw_tree.c

    r6ff1f1e r45b26dad  
    9898 * @return NULL if there is no such child or pointer to the matching child node.
    9999 */
    100 static ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name)
     100ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name)
    101101{
    102102        ofw_tree_node_t *cur;
     
    125125}
    126126
     127/** Lookup first child of given device type.
     128 *
     129 * @param node Node whose child is being looked up.
     130 * @param name Device type of the child being looked up.
     131 *
     132 * @return NULL if there is no such child or pointer to the matching child node.
     133 */
     134ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name)
     135{
     136        ofw_tree_node_t *cur;
     137        ofw_tree_property_t *prop;
     138       
     139        for (cur = node->child; cur; cur = cur->peer) {
     140                prop = ofw_tree_getprop(cur, "device_type");
     141                if (!prop || !prop->value)
     142                        continue;
     143                if (strcmp(prop->value, name) == 0)
     144                        return cur;
     145        }
     146                       
     147        return NULL;
     148}
     149
     150/** Lookup first peer of given device type.
     151 *
     152 * @param node Node whose peer is being looked up.
     153 * @param name Device type of the child being looked up.
     154 *
     155 * @return NULL if there is no such child or pointer to the matching child node.
     156 */
     157ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name)
     158{
     159        ofw_tree_node_t *cur;
     160        ofw_tree_property_t *prop;
     161       
     162        for (cur = node->peer; cur; cur = cur->peer) {
     163                prop = ofw_tree_getprop(cur, "device_type");
     164                if (!prop || !prop->value)
     165                        continue;
     166                if (strcmp(prop->value, name) == 0)
     167                        return cur;
     168        }
     169                       
     170        return NULL;
     171}
     172
     173
    127174/** Lookup OpenFirmware node by its path.
    128175 *
Note: See TracChangeset for help on using the changeset viewer.