Changeset 965dc18 in mainline for boot/arch/sparc64/loader
- Timestamp:
- 2008-12-05T19:59:03Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 49093a4
- Parents:
- 0258e67
- Location:
- boot/arch/sparc64/loader
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/arch/sparc64/loader/asm.S
r0258e67 r965dc18 106 106 * 2. Invalidate I-cache. 107 107 * 3. Flush instruction pipeline. 108 */ 109 call icache_flush 110 membar #StoreStore 108 */ 109 110 /* 111 * US3 processors have a write-invalidate cache, so explicitly 112 * invalidating it is not required. Whether to invalidate I-cache 113 * or not is decided according to the value of the global 114 * "subarchitecture" variable (set in the bootstrap). 115 */ 116 set subarchitecture, %g2 117 ldub [%g2], %g2 118 cmp %g2, 3 119 be 1f 120 nop 121 0: 122 call icache_flush 123 nop 124 1: 125 membar #StoreStore 126 127 /* 128 * Flush the instruction pipeline. 129 */ 111 130 flush %i7 112 131 … … 135 154 ! SF Erratum #51 136 155 nop 137 138 156 .global ofw 139 157 ofw: -
boot/arch/sparc64/loader/main.c
r0258e67 r965dc18 40 40 41 41 bootinfo_t bootinfo; 42 42 43 component_t components[COMPONENTS]; 43 44 … … 55 56 char *timestamp = ""; 56 57 #endif 58 59 /** UltraSPARC subarchitecture - 1 for US, 3 for US3 */ 60 uint8_t subarchitecture; 61 62 /** 63 * mask of the MID field inside the ICBUS_CONFIG register shifted by 64 * MID_SHIFT bits to the right 65 */ 66 uint16_t mid_mask; 57 67 58 68 /** Print version information. */ … … 64 74 } 65 75 76 /* the lowest ID (read from the VER register) of some US3 CPU model */ 77 #define FIRST_US3_CPU 0x14 78 79 /* the greatest ID (read from the VER register) of some US3 CPU model */ 80 #define LAST_US3_CPU 0x19 81 82 /* UltraSPARC IIIi processor implementation code */ 83 #define US_IIIi_CODE 0x15 84 85 /** 86 * Sets the global variables "subarchitecture" and "mid_mask" to 87 * correct values. 88 */ 89 static void detect_subarchitecture(void) 90 { 91 uint64_t v; 92 asm volatile ("rdpr %%ver, %0\n" : "=r" (v)); 93 94 v = (v << 16) >> 48; 95 if ((v >= FIRST_US3_CPU) && (v <= LAST_US3_CPU)) { 96 subarchitecture = SUBARCH_US3; 97 if (v == US_IIIi_CODE) 98 mid_mask = (1 << 5) - 1; 99 else 100 mid_mask = (1 << 10) - 1; 101 } else if (v < FIRST_US3_CPU) { 102 subarchitecture = SUBARCH_US; 103 mid_mask = (1 << 5) - 1; 104 } else { 105 printf("\nThis CPU is not supported by HelenOS."); 106 } 107 } 108 66 109 void bootstrap(void) 67 110 { … … 73 116 version_print(); 74 117 118 detect_subarchitecture(); 75 119 init_components(components); 76 120 … … 84 128 halt(); 85 129 } 86 130 87 131 if (bootinfo.memmap.total == 0) { 88 132 printf("Error: no memory detected, halting.\n"); -
boot/arch/sparc64/loader/main.h
r0258e67 r965dc18 42 42 #define AP_PROCESSOR 0 43 43 44 #define SUBARCH_US 1 45 #define SUBARCH_US3 3 46 44 47 typedef struct { 45 48 void *addr; -
boot/arch/sparc64/loader/ofwarch.c
r0258e67 r965dc18 41 41 #include "asm.h" 42 42 43 /* these tho variables will be set by the detect_subarchitecture function */ 44 extern uint8_t subarchitecture; 45 extern uint16_t mid_mask; 46 43 47 void write(const char *str, const int len) 44 48 { … … 57 61 } 58 62 59 int ofw_cpu(void) 63 /** 64 * Starts all CPUs represented by following siblings of the given node, 65 * except for the current CPU. 66 * 67 * @param child The first child of the OFW tree node whose children 68 * represent CPUs to be woken up. 69 * @param current_mid MID of the current CPU, the current CPU will 70 * (of course) not be woken up. 71 * @return Number of CPUs which have the same parent node as 72 * "child". 73 */ 74 static int wake_cpus_in_node(phandle child, uint64_t current_mid) 60 75 { 76 int cpus; 61 77 char type_name[BUF_SIZE]; 62 63 phandle node;64 node = ofw_get_child_node(ofw_root);65 if (node == 0 || node == -1) {66 printf("Could not find any child nodes of the root node.\n");67 return 0;68 }69 78 70 uint64_t current_mid; 71 72 asm volatile ("ldxa [%1] %2, %0\n" 73 : "=r" (current_mid) 74 : "r" (0), "i" (ASI_UPA_CONFIG)); 75 current_mid >>= UPA_CONFIG_MID_SHIFT; 76 current_mid &= UPA_CONFIG_MID_MASK; 77 78 int cpus; 79 80 for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node), 81 cpus++) { 82 if (ofw_get_property(node, "device_type", type_name, 79 for (cpus = 0; child != 0 && child != -1; 80 child = ofw_get_peer_node(child), cpus++) { 81 if (ofw_get_property(child, "device_type", type_name, 83 82 sizeof(type_name)) > 0) { 84 83 if (strcmp(type_name, "cpu") == 0) { 85 84 uint32_t mid; 86 85 87 if (ofw_get_property(node, "upa-portid", &mid, 88 sizeof(mid)) <= 0) 86 /* 87 * "upa-portid" for US, "portid" for US-III, 88 * "cpuid" for US-IV 89 */ 90 if (ofw_get_property( 91 child, "upa-portid", 92 &mid, sizeof(mid)) <= 0 93 && ofw_get_property(child, "portid", 94 &mid, sizeof(mid)) <= 0 95 && ofw_get_property(child, "cpuid", 96 &mid, sizeof(mid)) <= 0) 89 97 continue; 90 98 … … 94 102 */ 95 103 (void) ofw_call("SUNW,start-cpu", 3, 1, 96 NULL, node, KERNEL_VIRTUAL_ADDRESS,104 NULL, child, KERNEL_VIRTUAL_ADDRESS, 97 105 bootinfo.physmem_start | 98 106 AP_PROCESSOR); … … 105 113 } 106 114 115 /** 116 * Finds out the current CPU's MID and wakes up all AP processors. 117 */ 118 int ofw_cpu(void) 119 { 120 int cpus; 121 phandle node; 122 phandle subnode; 123 phandle cpus_parent; 124 phandle cmp; 125 char name[BUF_SIZE]; 126 127 /* get the current CPU MID */ 128 uint64_t current_mid; 129 130 asm volatile ("ldxa [%1] %2, %0\n" 131 : "=r" (current_mid) 132 : "r" (0), "i" (ASI_ICBUS_CONFIG)); 133 current_mid >>= ICBUS_CONFIG_MID_SHIFT; 134 135 current_mid &= mid_mask; 136 137 /* wake up CPUs */ 138 139 cpus_parent = ofw_find_device("/ssm@0,0"); 140 if (cpus_parent == 0 || cpus_parent == -1) { 141 cpus_parent = ofw_find_device("/"); 142 } 143 144 node = ofw_get_child_node(cpus_parent); 145 cpus = wake_cpus_in_node(node, current_mid); 146 while (node != 0 && node != -1) { 147 if (ofw_get_property(node, "name", name, 148 sizeof(name)) > 0) { 149 if (strcmp(name, "cmp") == 0) { 150 subnode = ofw_get_child_node(node); 151 cpus += wake_cpus_in_node(subnode, 152 current_mid); 153 } 154 } 155 node = ofw_get_peer_node(node); 156 } 157 158 return cpus; 159 160 } 161 107 162 /** Get physical memory starting address. 108 163 * 109 * @param start 110 * 164 * @param start Pointer to variable where the physical memory starting 165 * address will be stored. 111 166 * 112 * @return 167 * @return Non-zero on succes, zero on failure. 113 168 */ 114 169 int ofw_get_physmem_start(uintptr_t *start) -
boot/arch/sparc64/loader/register.h
r0258e67 r965dc18 34 34 #define PSTATE_AM_BIT 8 35 35 36 #define ASI_UPA_CONFIG 0x4a 37 #define UPA_CONFIG_MID_SHIFT 17 38 #define UPA_CONFIG_MID_MASK 0x1f 36 #define ASI_ICBUS_CONFIG 0x4a 37 #define ICBUS_CONFIG_MID_SHIFT 17 39 38 40 39 #endif
Note:
See TracChangeset
for help on using the changeset viewer.