/trunk/boot/boot.config |
---|
83,5 → 83,8 |
@ "fat" FAT16 image |
! RDFMT (choice) |
# Preserve A.OUT header in isofs.b |
! [ARCH=sparc64] CONFIG_AOUT_ISOFS_B (y/n) |
# External ramdisk |
! [ARCH=sparc64] CONFIG_RD_EXTERNAL (y/n) |
/trunk/boot/genarch/balloc.h |
---|
31,7 → 31,7 |
#include <types.h> |
#define BALLOC_MAX_SIZE (1024 * 1024) |
#define BALLOC_MAX_SIZE (128 * 1024) |
typedef struct { |
uintptr_t base; |
/trunk/boot/genarch/ofw_tree.c |
---|
121,7 → 121,6 |
memcpy(current_node->da_name, &path[i], len); |
current_node->da_name[len] = '\0'; |
/* |
* Recursively process the potential child node. |
*/ |
219,10 → 218,28 |
ofw_tree_node_t *ofw_tree_build(void) |
{ |
ofw_tree_node_t *root; |
phandle ssm_node; |
ofw_tree_node_t *ssm; |
root = ofw_tree_node_alloc(); |
if (root) |
ofw_tree_node_process(root, NULL, ofw_root); |
/* |
* The firmware client interface does not automatically include the |
* "ssm" node in the list of children of "/". A nasty yet working |
* solution is to explicitly stick "ssm" to the OFW tree. |
*/ |
ssm_node = ofw_find_device("/ssm@0,0"); |
if (ssm_node != -1) { |
ssm = ofw_tree_node_alloc(); |
if (ssm) { |
ofw_tree_node_process( |
ssm, root, ofw_find_device("/ssm@0,0")); |
ssm->peer = root->child; |
root->child = ssm; |
} |
} |
return root; |
} |
/trunk/boot/genarch/ofw.c |
---|
48,7 → 48,8 |
if (ofw_chosen == -1) |
halt(); |
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0) |
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, |
sizeof(ofw_stdout)) <= 0) |
ofw_stdout = 0; |
ofw_root = ofw_find_device("/"); |
57,11 → 58,13 |
halt(); |
} |
if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) { |
if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, |
sizeof(ofw_mmu)) <= 0) { |
puts("\r\nError: Unable to get mmu property, halted.\r\n"); |
halt(); |
} |
if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop, sizeof(ofw_memory_prop)) <= 0) { |
if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop, |
sizeof(ofw_memory_prop)) <= 0) { |
puts("\r\nError: Unable to get memory property, halted.\r\n"); |
halt(); |
} |
83,12 → 86,16 |
* |
* @param service String identifying the service requested. |
* @param nargs Number of input arguments. |
* @param nret Number of output arguments. This includes the return value. |
* @param rets Buffer for output arguments or NULL. The buffer must accommodate nret - 1 items. |
* @param nret Number of output arguments. This includes the return |
* value. |
* @param rets Buffer for output arguments or NULL. The buffer must |
* accommodate nret - 1 items. |
* |
* @return Return value returned by the client interface. |
*/ |
unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...) |
unsigned long |
ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, |
...) |
{ |
va_list list; |
ofw_args_t args; |
119,7 → 126,9 |
return ofw_call("finddevice", 1, 1, NULL, name); |
} |
int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen) |
int |
ofw_get_property(const phandle device, const char *name, void *buf, |
const int buflen) |
{ |
return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen); |
} |
144,7 → 153,8 |
unsigned int ret = 1; |
if (ofw_get_property(device, "#address-cells", &ret, sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#address-cells", &ret, sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#address-cells", &ret, |
sizeof(ret)) <= 0) |
ret = OFW_ADDRESS_CELLS; |
return ret; |
156,7 → 166,8 |
unsigned int ret; |
if (ofw_get_property(device, "#size-cells", &ret, sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#size-cells", &ret, sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#size-cells", &ret, |
sizeof(ret)) <= 0) |
ret = OFW_SIZE_CELLS; |
return ret; |
192,7 → 203,8 |
ofw_arg_t result[4]; |
int shift; |
if (ofw_call("call-method", 3, 5, result, "translate", ofw_mmu, virt) != 0) { |
if (ofw_call("call-method", 3, 5, result, "translate", ofw_mmu, |
virt) != 0) { |
puts("Error: MMU method translate() failed, halting.\n"); |
halt(); |
} |
212,7 → 224,8 |
{ |
ofw_arg_t retaddr; |
if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len, virt) != 0) { |
if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len, |
virt) != 0) { |
puts("Error: MMU method claim() failed, halting.\n"); |
halt(); |
} |
269,8 → 282,8 |
phys_lo = (uintptr_t) phys; |
} |
return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size, virt, |
phys_hi, phys_lo); |
return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size, |
virt, phys_hi, phys_lo); |
} |
/** Save OpenFirmware physical memory map. |
281,10 → 294,13 |
*/ |
int ofw_memmap(memmap_t *map) |
{ |
unsigned int ac = ofw_get_address_cells(ofw_memory); |
unsigned int sc = ofw_get_size_cells(ofw_memory); |
unsigned int ac = ofw_get_address_cells(ofw_memory) / |
(sizeof(uintptr_t) / sizeof(uint32_t)); |
unsigned int sc = ofw_get_size_cells(ofw_memory) / |
(sizeof(uintptr_t) / sizeof(uint32_t)); |
printf("address cells: %d, size cells: %d. ", ac, sc); |
uint32_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)]; |
uintptr_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)]; |
int ret = ofw_get_property(ofw_memory, "reg", buf, sizeof(buf)); |
if (ret <= 0) /* ret is the number of written bytes */ |
return false; |
292,11 → 308,22 |
int pos; |
map->total = 0; |
map->count = 0; |
for (pos = 0; (pos < ret / sizeof(uint32_t)) && |
for (pos = 0; (pos < ret / sizeof(uintptr_t)) && |
(map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) { |
void * start = (void *) ((uintptr_t) buf[pos + ac - 1]); |
void *start = (void *) (buf[pos + ac - 1]); |
unsigned int size = buf[pos + ac + sc - 1]; |
/* |
* This is a hot fix of the issue which occurs on machines |
* where there are holes in the physical memory (such as |
* SunBlade 1500). Should we detect a hole in the physical |
* memory, we will ignore any memory detected behind |
* the hole and pretend the hole does not exist. |
*/ |
if ((map->count > 0) && (map->zones[map->count - 1].start + |
map->zones[map->count - 1].size < start)) |
break; |
if (size > 0) { |
map->zones[map->count].start = start; |
map->zones[map->count].size = size; |
308,13 → 335,13 |
return true; |
} |
int ofw_screen(screen_t *screen) |
{ |
char device_name[BUF_SIZE]; |
uint32_t virtaddr; |
if (ofw_get_property(ofw_aliases, "screen", device_name, sizeof(device_name)) <= 0) |
if (ofw_get_property(ofw_aliases, "screen", device_name, |
sizeof(device_name)) <= 0) |
return false; |
phandle device = ofw_find_device(device_name); |
321,21 → 348,26 |
if (device == -1) |
return false; |
if (ofw_get_property(device, "address", &virtaddr, sizeof(virtaddr)) <= 0) |
if (ofw_get_property(device, "address", &virtaddr, |
sizeof(virtaddr)) <= 0) |
return false; |
screen->addr = (void *) ((uintptr_t) virtaddr); |
if (ofw_get_property(device, "width", &screen->width, sizeof(screen->width)) <= 0) |
if (ofw_get_property(device, "width", &screen->width, |
sizeof(screen->width)) <= 0) |
return false; |
if (ofw_get_property(device, "height", &screen->height, sizeof(screen->height)) <= 0) |
if (ofw_get_property(device, "height", &screen->height, |
sizeof(screen->height)) <= 0) |
return false; |
if (ofw_get_property(device, "depth", &screen->bpp, sizeof(screen->bpp)) <= 0) |
if (ofw_get_property(device, "depth", &screen->bpp, |
sizeof(screen->bpp)) <= 0) |
return false; |
if (ofw_get_property(device, "linebytes", &screen->scanline, sizeof(screen->scanline)) <= 0) |
if (ofw_get_property(device, "linebytes", &screen->scanline, |
sizeof(screen->scanline)) <= 0) |
return false; |
return true; |
/trunk/boot/arch/sparc64/Makefile.inc |
---|
28,6 → 28,14 |
TMP = distroot |
ifeq ($(CONFIG_AOUT_ISOFS_B),n) |
SILO_PACKAGE=silo.patched.tar.gz |
endif |
ifeq ($(CONFIG_AOUT_ISOFS_B),y) |
SILO_PACKAGE=silo.tar.gz |
endif |
build: $(BASE)/image.iso |
ifeq ($(CONFIG_RD_EXTERNAL),y) |
39,7 → 47,7 |
$(BASE)/image.iso: depend arch/$(ARCH)/loader/image.boot |
mkdir -p $(TMP)/boot |
mkdir -p $(TMP)/HelenOS |
cat arch/$(ARCH)/silo/silo.tar.gz | (cd $(TMP)/boot; tar xvfz -) |
cat arch/$(ARCH)/silo/$(SILO_PACKAGE) | (cd $(TMP)/boot; tar xvfz -) |
cp arch/$(ARCH)/silo/README arch/$(ARCH)/silo/COPYING $(TMP)/boot |
cat arch/$(ARCH)/silo/silo.conf | $(SILO_CONF_FILTER) >$(TMP)/boot/silo.conf |
cp arch/$(ARCH)/loader/image.boot $(TMP)/HelenOS/image.boot |
/trunk/boot/arch/sparc64/loader/asm.S |
---|
106,8 → 106,27 |
* 2. Invalidate I-cache. |
* 3. Flush instruction pipeline. |
*/ |
/* |
* US3 processors have a write-invalidate cache, so explicitly |
* invalidating it is not required. Whether to invalidate I-cache |
* or not is decided according to the value of the global |
* "subarchitecture" variable (set in the bootstrap). |
*/ |
set subarchitecture, %g2 |
ldub [%g2], %g2 |
cmp %g2, 3 |
be 1f |
nop |
0: |
call icache_flush |
nop |
1: |
membar #StoreStore |
/* |
* Flush the instruction pipeline. |
*/ |
flush %i7 |
mov %o0, %l1 |
134,7 → 153,6 |
retl |
! SF Erratum #51 |
nop |
.global ofw |
ofw: |
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp |
/trunk/boot/arch/sparc64/loader/main.c |
---|
39,6 → 39,7 |
#include <string.h> |
bootinfo_t bootinfo; |
component_t components[COMPONENTS]; |
char *release = RELEASE; |
55,6 → 56,15 |
char *timestamp = ""; |
#endif |
/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */ |
uint8_t subarchitecture; |
/** |
* mask of the MID field inside the ICBUS_CONFIG register shifted by |
* MID_SHIFT bits to the right |
*/ |
uint16_t mid_mask; |
/** Print version information. */ |
static void version_print(void) |
{ |
63,6 → 73,39 |
release, revision, timestamp); |
} |
/* the lowest ID (read from the VER register) of some US3 CPU model */ |
#define FIRST_US3_CPU 0x14 |
/* the greatest ID (read from the VER register) of some US3 CPU model */ |
#define LAST_US3_CPU 0x19 |
/* UltraSPARC IIIi processor implementation code */ |
#define US_IIIi_CODE 0x15 |
/** |
* Sets the global variables "subarchitecture" and "mid_mask" to |
* correct values. |
*/ |
static void detect_subarchitecture(void) |
{ |
uint64_t v; |
asm volatile ("rdpr %%ver, %0\n" : "=r" (v)); |
v = (v << 16) >> 48; |
if ((v >= FIRST_US3_CPU) && (v <= LAST_US3_CPU)) { |
subarchitecture = SUBARCH_US3; |
if (v == US_IIIi_CODE) |
mid_mask = (1 << 5) - 1; |
else |
mid_mask = (1 << 10) - 1; |
} else if (v < FIRST_US3_CPU) { |
subarchitecture = SUBARCH_US; |
mid_mask = (1 << 5) - 1; |
} else { |
printf("\nThis CPU is not supported by HelenOS."); |
} |
} |
void bootstrap(void) |
{ |
void *base = (void *) KERNEL_VIRTUAL_ADDRESS; |
72,6 → 115,7 |
version_print(); |
detect_subarchitecture(); |
init_components(components); |
if (!ofw_get_physmem_start(&bootinfo.physmem_start)) { |
/trunk/boot/arch/sparc64/loader/main.h |
---|
41,6 → 41,9 |
#define BSP_PROCESSOR 1 |
#define AP_PROCESSOR 0 |
#define SUBARCH_US 1 |
#define SUBARCH_US3 3 |
typedef struct { |
void *addr; |
uint32_t size; |
/trunk/boot/arch/sparc64/loader/ofwarch.c |
---|
40,6 → 40,10 |
#include "main.h" |
#include "asm.h" |
/* these tho variables will be set by the detect_subarchitecture function */ |
extern uint8_t subarchitecture; |
extern uint16_t mid_mask; |
void write(const char *str, const int len) |
{ |
int i; |
56,36 → 60,40 |
return flag != -1; |
} |
int ofw_cpu(void) |
/** |
* Starts all CPUs represented by following siblings of the given node, |
* except for the current CPU. |
* |
* @param child The first child of the OFW tree node whose children |
* represent CPUs to be woken up. |
* @param current_mid MID of the current CPU, the current CPU will |
* (of course) not be woken up. |
* @return Number of CPUs which have the same parent node as |
* "child". |
*/ |
static int wake_cpus_in_node(phandle child, uint64_t current_mid) |
{ |
int cpus; |
char type_name[BUF_SIZE]; |
phandle node; |
node = ofw_get_child_node(ofw_root); |
if (node == 0 || node == -1) { |
printf("Could not find any child nodes of the root node.\n"); |
return 0; |
} |
uint64_t current_mid; |
asm volatile ("ldxa [%1] %2, %0\n" |
: "=r" (current_mid) |
: "r" (0), "i" (ASI_UPA_CONFIG)); |
current_mid >>= UPA_CONFIG_MID_SHIFT; |
current_mid &= UPA_CONFIG_MID_MASK; |
int cpus; |
for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node), |
cpus++) { |
if (ofw_get_property(node, "device_type", type_name, |
for (cpus = 0; child != 0 && child != -1; |
child = ofw_get_peer_node(child), cpus++) { |
if (ofw_get_property(child, "device_type", type_name, |
sizeof(type_name)) > 0) { |
if (strcmp(type_name, "cpu") == 0) { |
uint32_t mid; |
if (ofw_get_property(node, "upa-portid", &mid, |
sizeof(mid)) <= 0) |
/* |
* "upa-portid" for US, "portid" for US-III, |
* "cpuid" for US-IV |
*/ |
if (ofw_get_property( |
child, "upa-portid", |
&mid, sizeof(mid)) <= 0 |
&& ofw_get_property(child, "portid", |
&mid, sizeof(mid)) <= 0 |
&& ofw_get_property(child, "cpuid", |
&mid, sizeof(mid)) <= 0) |
continue; |
if (current_mid != mid) { |
93,7 → 101,7 |
* Start secondary processor. |
*/ |
(void) ofw_call("SUNW,start-cpu", 3, 1, |
NULL, node, KERNEL_VIRTUAL_ADDRESS, |
NULL, child, KERNEL_VIRTUAL_ADDRESS, |
bootinfo.physmem_start | |
AP_PROCESSOR); |
} |
104,6 → 112,53 |
return cpus; |
} |
/** |
* Finds out the current CPU's MID and wakes up all AP processors. |
*/ |
int ofw_cpu(void) |
{ |
int cpus; |
phandle node; |
phandle subnode; |
phandle cpus_parent; |
phandle cmp; |
char name[BUF_SIZE]; |
/* get the current CPU MID */ |
uint64_t current_mid; |
asm volatile ("ldxa [%1] %2, %0\n" |
: "=r" (current_mid) |
: "r" (0), "i" (ASI_ICBUS_CONFIG)); |
current_mid >>= ICBUS_CONFIG_MID_SHIFT; |
current_mid &= mid_mask; |
/* wake up CPUs */ |
cpus_parent = ofw_find_device("/ssm@0,0"); |
if (cpus_parent == 0 || cpus_parent == -1) { |
cpus_parent = ofw_find_device("/"); |
} |
node = ofw_get_child_node(cpus_parent); |
cpus = wake_cpus_in_node(node, current_mid); |
while (node != 0 && node != -1) { |
if (ofw_get_property(node, "name", name, |
sizeof(name)) > 0) { |
if (strcmp(name, "cmp") == 0) { |
subnode = ofw_get_child_node(node); |
cpus += wake_cpus_in_node(subnode, |
current_mid); |
} |
} |
node = ofw_get_peer_node(node); |
} |
return cpus; |
} |
/** Get physical memory starting address. |
* |
* @param start Pointer to variable where the physical memory starting |
/trunk/boot/arch/sparc64/loader/register.h |
---|
33,8 → 33,7 |
#define PSTATE_PRIV_BIT 4 |
#define PSTATE_AM_BIT 8 |
#define ASI_UPA_CONFIG 0x4a |
#define UPA_CONFIG_MID_SHIFT 17 |
#define UPA_CONFIG_MID_MASK 0x1f |
#define ASI_ICBUS_CONFIG 0x4a |
#define ICBUS_CONFIG_MID_SHIFT 17 |
#endif |
/trunk/boot/arch/sparc64/silo/silo.patched.tar.gz |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/boot/arch/ppc64/Makefile.inc |
---|
26,6 → 26,8 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
DEFS += -DOPEN_BOOT |
build: $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot |
35,7 → 37,7 |
-rm arch/$(ARCH)/loader/image.boot |
arch/$(ARCH)/loader/image.boot: |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)" |
clean: generic_clean |
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |