aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2005-09-23 00:56:09 -0400
committerStephen Rothwell <sfr@canb.auug.org.au>2005-09-23 00:56:09 -0400
commitc0a59491daca7db11d49edad1a1cefaaa7120a9e (patch)
treeea7947639fd442a15f57962f4350998b3c2ccbb3 /arch/ppc64
parentf6ab9c68406dfcd1fcd0a5352244fcb932b113b1 (diff)
ppc64 iSeries: Create a fake flat device tree on iSeries
This patch adds infrastructure for creating a fake flattened device tree on iSeries. We also need to build prom.o for iSeries which means we'll always need it. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Diffstat (limited to 'arch/ppc64')
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index 49d0f9999682..99e4307affd6 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -912,7 +912,144 @@ struct machdep_calls __initdata iseries_md = {
912 /* XXX Implement enable_pmcs for iSeries */ 912 /* XXX Implement enable_pmcs for iSeries */
913}; 913};
914 914
915struct blob {
916 unsigned char data[PAGE_SIZE];
917 unsigned long next;
918};
919
920struct iseries_flat_dt {
921 struct boot_param_header header;
922 u64 reserve_map[2];
923 struct blob dt;
924 struct blob strings;
925};
926
927struct iseries_flat_dt iseries_dt;
928
929void dt_init(struct iseries_flat_dt *dt)
930{
931 dt->header.off_mem_rsvmap =
932 offsetof(struct iseries_flat_dt, reserve_map);
933 dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt);
934 dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings);
935 dt->header.totalsize = sizeof(struct iseries_flat_dt);
936 dt->header.dt_strings_size = sizeof(struct blob);
937
938 /* There is no notion of hardware cpu id on iSeries */
939 dt->header.boot_cpuid_phys = smp_processor_id();
940
941 dt->dt.next = (unsigned long)&dt->dt.data;
942 dt->strings.next = (unsigned long)&dt->strings.data;
943
944 dt->header.magic = OF_DT_HEADER;
945 dt->header.version = 0x10;
946 dt->header.last_comp_version = 0x10;
947
948 dt->reserve_map[0] = 0;
949 dt->reserve_map[1] = 0;
950}
951
952void dt_check_blob(struct blob *b)
953{
954 if (b->next >= (unsigned long)&b->next) {
955 DBG("Ran out of space in flat device tree blob!\n");
956 BUG();
957 }
958}
959
960void dt_push_u32(struct iseries_flat_dt *dt, u32 value)
961{
962 *((u32*)dt->dt.next) = value;
963 dt->dt.next += sizeof(u32);
964
965 dt_check_blob(&dt->dt);
966}
967
968void dt_push_u64(struct iseries_flat_dt *dt, u64 value)
969{
970 *((u64*)dt->dt.next) = value;
971 dt->dt.next += sizeof(u64);
972
973 dt_check_blob(&dt->dt);
974}
975
976unsigned long dt_push_bytes(struct blob *blob, char *data, int len)
977{
978 unsigned long start = blob->next - (unsigned long)blob->data;
979
980 memcpy((char *)blob->next, data, len);
981 blob->next = _ALIGN(blob->next + len, 4);
982
983 dt_check_blob(blob);
984
985 return start;
986}
987
988void dt_start_node(struct iseries_flat_dt *dt, char *name)
989{
990 dt_push_u32(dt, OF_DT_BEGIN_NODE);
991 dt_push_bytes(&dt->dt, name, strlen(name) + 1);
992}
993
994#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
995
996void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len)
997{
998 unsigned long offset;
999
1000 dt_push_u32(dt, OF_DT_PROP);
1001
1002 /* Length of the data */
1003 dt_push_u32(dt, len);
1004
1005 /* Put the property name in the string blob. */
1006 offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1);
1007
1008 /* The offset of the properties name in the string blob. */
1009 dt_push_u32(dt, (u32)offset);
1010
1011 /* The actual data. */
1012 dt_push_bytes(&dt->dt, data, len);
1013}
1014
1015void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data)
1016{
1017 dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */
1018}
1019
1020void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data)
1021{
1022 dt_prop(dt, name, (char *)&data, sizeof(u32));
1023}
1024
1025void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data)
1026{
1027 dt_prop(dt, name, (char *)&data, sizeof(u64));
1028}
1029
1030void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n)
1031{
1032 dt_prop(dt, name, (char *)data, sizeof(u64) * n);
1033}
1034
1035void dt_prop_empty(struct iseries_flat_dt *dt, char *name)
1036{
1037 dt_prop(dt, name, NULL, 0);
1038}
1039
1040void build_flat_dt(struct iseries_flat_dt *dt)
1041{
1042 dt_init(dt);
1043
1044 dt_start_node(dt, "");
1045 dt_end_node(dt);
1046
1047 dt_push_u32(dt, OF_DT_END);
1048}
1049
915void __init iSeries_early_setup(void) 1050void __init iSeries_early_setup(void)
916{ 1051{
917 iSeries_fixup_klimit(); 1052 iSeries_fixup_klimit();
1053
1054 build_flat_dt(&iseries_dt);
918} 1055}