Blame SOURCES/0228-powerpc-do-CAS-in-a-more-compatible-way.patch

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