d15d46b
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
d15d46b
From: Daniel Axtens <dja@axtens.net>
d15d46b
Date: Fri, 8 Apr 2022 12:35:28 +1000
d15d46b
Subject: [PATCH] powerpc: do CAS in a more compatible way
d15d46b
d15d46b
I wrongly assumed that the most compatible way to perform CAS
d15d46b
negotiation was to only set the minimum number of vectors required
d15d46b
to ask for more memory. It turns out that this messes up booting
d15d46b
if the minimum VP capacity would be less than the default 10% in
d15d46b
vector 4.
d15d46b
d15d46b
Linux configures the minimum capacity to be 1%, so copy it for that
d15d46b
and for vector 3 which we now need to specify as well.
d15d46b
d15d46b
Signed-off-by: Daniel Axtens <dja@axtens.net>
d15d46b
---
d15d46b
 grub-core/kern/ieee1275/init.c | 54 ++++++++++++++++++++++++------------------
d15d46b
 1 file changed, 31 insertions(+), 23 deletions(-)
d15d46b
d15d46b
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
d15d46b
index 9704715c83..ef55107467 100644
d15d46b
--- a/grub-core/kern/ieee1275/init.c
d15d46b
+++ b/grub-core/kern/ieee1275/init.c
d15d46b
@@ -298,33 +298,37 @@ grub_ieee1275_total_mem (grub_uint64_t *total)
d15d46b
 
d15d46b
 /* Based on linux - arch/powerpc/kernel/prom_init.c */
d15d46b
 struct option_vector2 {
d15d46b
-	grub_uint8_t byte1;
d15d46b
-	grub_uint16_t reserved;
d15d46b
-	grub_uint32_t real_base;
d15d46b
-	grub_uint32_t real_size;
d15d46b
-	grub_uint32_t virt_base;
d15d46b
-	grub_uint32_t virt_size;
d15d46b
-	grub_uint32_t load_base;
d15d46b
-	grub_uint32_t min_rma;
d15d46b
-	grub_uint32_t min_load;
d15d46b
-	grub_uint8_t min_rma_percent;
d15d46b
-	grub_uint8_t max_pft_size;
d15d46b
+  grub_uint8_t byte1;
d15d46b
+  grub_uint16_t reserved;
d15d46b
+  grub_uint32_t real_base;
d15d46b
+  grub_uint32_t real_size;
d15d46b
+  grub_uint32_t virt_base;
d15d46b
+  grub_uint32_t virt_size;
d15d46b
+  grub_uint32_t load_base;
d15d46b
+  grub_uint32_t min_rma;
d15d46b
+  grub_uint32_t min_load;
d15d46b
+  grub_uint8_t min_rma_percent;
d15d46b
+  grub_uint8_t max_pft_size;
d15d46b
 } __attribute__((packed));
d15d46b
 
d15d46b
 struct pvr_entry {
d15d46b
-	  grub_uint32_t mask;
d15d46b
-	  grub_uint32_t entry;
d15d46b
+  grub_uint32_t mask;
d15d46b
+  grub_uint32_t entry;
d15d46b
 };
d15d46b
 
d15d46b
 struct cas_vector {
d15d46b
-    struct {
d15d46b
-      struct pvr_entry terminal;
d15d46b
-    } pvr_list;
d15d46b
-    grub_uint8_t num_vecs;
d15d46b
-    grub_uint8_t vec1_size;
d15d46b
-    grub_uint8_t vec1;
d15d46b
-    grub_uint8_t vec2_size;
d15d46b
-    struct option_vector2 vec2;
d15d46b
+  struct {
d15d46b
+    struct pvr_entry terminal;
d15d46b
+  } pvr_list;
d15d46b
+  grub_uint8_t num_vecs;
d15d46b
+  grub_uint8_t vec1_size;
d15d46b
+  grub_uint8_t vec1;
d15d46b
+  grub_uint8_t vec2_size;
d15d46b
+  struct option_vector2 vec2;
d15d46b
+  grub_uint8_t vec3_size;
d15d46b
+  grub_uint16_t vec3;
d15d46b
+  grub_uint8_t vec4_size;
d15d46b
+  grub_uint16_t vec4;
d15d46b
 } __attribute__((packed));
d15d46b
 
d15d46b
 /* Call ibm,client-architecture-support to try to get more RMA.
d15d46b
@@ -345,13 +349,17 @@ grub_ieee1275_ibm_cas (void)
d15d46b
   } args;
d15d46b
   struct cas_vector vector = {
d15d46b
     .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
d15d46b
-    .num_vecs = 2 - 1,
d15d46b
+    .num_vecs = 4 - 1,
d15d46b
     .vec1_size = 0,
d15d46b
     .vec1 = 0x80, /* ignore */
d15d46b
     .vec2_size = 1 + sizeof(struct option_vector2) - 2,
d15d46b
     .vec2 = {
d15d46b
       0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48
d15d46b
     },
d15d46b
+    .vec3_size = 2 - 1,
d15d46b
+    .vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied
d15d46b
+    .vec4_size = 2 - 1,
d15d46b
+    .vec4 = 0x0001, // set required minimum capacity % to the lowest value
d15d46b
   };
d15d46b
 
d15d46b
   INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
d15d46b
@@ -364,7 +372,7 @@ grub_ieee1275_ibm_cas (void)
d15d46b
   args.ihandle = root;
d15d46b
   args.cas_addr = (grub_ieee1275_cell_t)&vector;
d15d46b
 
d15d46b
-  grub_printf("Calling ibm,client-architecture-support...");
d15d46b
+  grub_printf("Calling ibm,client-architecture-support from grub...");
d15d46b
   IEEE1275_CALL_ENTRY_FN (&args);
d15d46b
   grub_printf("done\n");
d15d46b