Re: [PATCH v3 gnumach] ACPI: Support XSDT (ACPI >= v2.0)

2024-01-31 Thread Samuel Thibault
Applied, thanks!

Damien Zammit, le mer. 31 janv. 2024 02:12:26 +, a ecrit:
> This enables gnumach to additionally parse the XSDT table
> if the revision of ACPI is 2.
> 
> TESTED: Still works on qemu (ACPI v1.0)
> TESTED: Works on a x86 board with XSDT (ACPI v2.0)
> ---
>  i386/i386at/acpi_parse_apic.c | 258 ++
>  i386/i386at/acpi_parse_apic.h |  18 ++-
>  i386/i386at/model_dep.c   |   8 +-
>  3 files changed, 195 insertions(+), 89 deletions(-)
> 
> diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
> index 1aef53ed..dcd5da89 100644
> --- a/i386/i386at/acpi_parse_apic.c
> +++ b/i386/i386at/acpi_parse_apic.c
> @@ -43,13 +43,12 @@ unsigned lapic_addr;
>   * and the number of entries stored in RSDT.
>   */
>  void
> -acpi_print_info(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, int 
> acpi_rsdt_n)
> +acpi_print_info(phys_addr_t rsdp, void *rsdt, int acpi_rsdt_n)
>  {
>  
>  printf("ACPI:\n");
> -printf(" rsdp = %p; rsdp->rsdt_addr = %x\n", rsdp, rsdp->rsdt_addr);
> -printf(" rsdt = %p; rsdt->length = %x (n = %x)\n", rsdt, 
> rsdt->header.length,
> -   acpi_rsdt_n);
> +printf(" rsdp = 0x%lx\n", rsdp);
> +printf(" rsdt/xsdt = 0x%p (n = %d)\n", rsdt, acpi_rsdt_n);
>  }
>  
>  /*
> @@ -99,27 +98,45 @@ acpi_check_signature(const uint8_t table_signature[], 
> const char *real_signature
>   *
>   * Preconditions: RSDP pointer must not be NULL.
>   *
> - * Returns 0 if correct.
> + * Returns 1 if ACPI 1.0 and sets sdt_base
> + * Returns 2 if ACPI >= 2.0 and sets sdt_base
>   */
>  static int8_t
> -acpi_check_rsdp(struct acpi_rsdp *rsdp)
> +acpi_check_rsdp(struct acpi_rsdp2 *rsdp, phys_addr_t *sdt_base)
>  {
> -uint32_t checksum;
>  int is_rsdp;
> +uint8_t cksum;
>  
>  /* Check if rsdp signature match with the ACPI RSDP signature. */
> -is_rsdp = acpi_check_signature(rsdp->signature, ACPI_RSDP_SIG, 
> 8*sizeof(uint8_t));
> +is_rsdp = acpi_check_signature(rsdp->v1.signature, ACPI_RSDP_SIG, 
> 8*sizeof(uint8_t));
>  
>  if (is_rsdp != ACPI_SUCCESS)
>  return ACPI_BAD_SIGNATURE;
>  
> -/* If match, calculates rdsp checksum and check It. */
> -checksum = acpi_checksum(rsdp, sizeof(struct acpi_rsdp));
> +if (rsdp->v1.revision == 0) {
> +// ACPI 1.0
> +*sdt_base = rsdp->v1.rsdt_addr;
> +printf("ACPI v1.0\n");
> +cksum = acpi_checksum((void *)(>v1), sizeof(struct acpi_rsdp));
>  
> -if (checksum != 0)
> -return ACPI_BAD_CHECKSUM;
> +if (cksum != 0)
> +return ACPI_BAD_CHECKSUM;
>  
> -return ACPI_SUCCESS;
> +return 1;
> +
> +} else if (rsdp->v1.revision == 2) {
> +// ACPI >= 2.0
> +*sdt_base = rsdp->xsdt_addr;
> +printf("ACPI >= v2.0\n");
> +cksum = acpi_checksum((void *)rsdp, sizeof(struct acpi_rsdp2));
> +
> +if (cksum != 0)
> +return ACPI_BAD_CHECKSUM;
> +
> +return 2;
> +}
> +
> +return ACPI_NO_RSDP;
>  }
>  
>  /*
> @@ -147,38 +164,41 @@ acpi_check_rsdp_align(void *addr)
>   *
>   * Preconditions: The start address (addr) must be aligned.
>   *
> - * Returns the reference to rsdp structure if success, NULL if failure.
> + * Returns the physical address of rsdp structure if success, 0 if failure.
>   */
> -static struct acpi_rsdp*
> -acpi_search_rsdp(void *addr, uint32_t length)
> +static phys_addr_t
> +acpi_search_rsdp(void *addr, uint32_t length, int *is_64bit)
>  {
>  void *end;
> +int version = 0;
> +phys_addr_t sdt_base = 0;
>  
>  /* Search RDSP in memory space between addr and addr+lenght. */
>  for (end = addr+length; addr < end; addr += ACPI_RSDP_ALIGN) {
>  
>  /* Check if the current memory block stores the RDSP. */
> -if ((addr != NULL) && (acpi_check_rsdp(addr) == ACPI_SUCCESS)) {
> -/* If yes, return RSDP address */
> -return (struct acpi_rsdp*) addr;
> +if ((addr != NULL) && ((version = acpi_check_rsdp(addr, _base)) 
> > 0)) {
> +/* If yes, return RSDT/XSDT address */
> +*is_64bit = (version == 2);
> +return sdt_base;
>  }
>  }
>  
> -return NULL;
> +return 0;
>  }
>  
>  /*
>   * acpi_get_rsdp: tries to find the RSDP table,
>   * searching It in many memory ranges, as It's written in ACPI Specification.
>   *
> - * Returns the reference to RDSP structure if success, NULL if failure.
> + * Returns the reference to RDSP structure if success, 0 if failure.
>   */
> -static struct acpi_rsdp*
> -acpi_get_rsdp(void)
> +static phys_addr_t
> +acpi_get_rsdp(int *is_64bit)
>  {
>  uint16_t *start = 0;
>  phys_addr_t base = 0;
> -struct acpi_rsdp *rsdp = NULL;
> +phys_addr_t rsdp = 0;
>  
>  /* EDBA start address. */
>  start = (uint16_t*) phystokv(0x040e);
> @@ -186,40 +206,17 @@ acpi_get_rsdp(void)
>  
>  /* check alignment. */
>  if (acpi_check_rsdp_align((void *)base) == 

[PATCH v3 gnumach] ACPI: Support XSDT (ACPI >= v2.0)

2024-01-30 Thread Damien Zammit
This enables gnumach to additionally parse the XSDT table
if the revision of ACPI is 2.

TESTED: Still works on qemu (ACPI v1.0)
TESTED: Works on a x86 board with XSDT (ACPI v2.0)
---
 i386/i386at/acpi_parse_apic.c | 258 ++
 i386/i386at/acpi_parse_apic.h |  18 ++-
 i386/i386at/model_dep.c   |   8 +-
 3 files changed, 195 insertions(+), 89 deletions(-)

diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
index 1aef53ed..dcd5da89 100644
--- a/i386/i386at/acpi_parse_apic.c
+++ b/i386/i386at/acpi_parse_apic.c
@@ -43,13 +43,12 @@ unsigned lapic_addr;
  * and the number of entries stored in RSDT.
  */
 void
-acpi_print_info(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, int 
acpi_rsdt_n)
+acpi_print_info(phys_addr_t rsdp, void *rsdt, int acpi_rsdt_n)
 {
 
 printf("ACPI:\n");
-printf(" rsdp = %p; rsdp->rsdt_addr = %x\n", rsdp, rsdp->rsdt_addr);
-printf(" rsdt = %p; rsdt->length = %x (n = %x)\n", rsdt, 
rsdt->header.length,
-   acpi_rsdt_n);
+printf(" rsdp = 0x%lx\n", rsdp);
+printf(" rsdt/xsdt = 0x%p (n = %d)\n", rsdt, acpi_rsdt_n);
 }
 
 /*
@@ -99,27 +98,45 @@ acpi_check_signature(const uint8_t table_signature[], const 
char *real_signature
  *
  * Preconditions: RSDP pointer must not be NULL.
  *
- * Returns 0 if correct.
+ * Returns 1 if ACPI 1.0 and sets sdt_base
+ * Returns 2 if ACPI >= 2.0 and sets sdt_base
  */
 static int8_t
-acpi_check_rsdp(struct acpi_rsdp *rsdp)
+acpi_check_rsdp(struct acpi_rsdp2 *rsdp, phys_addr_t *sdt_base)
 {
-uint32_t checksum;
 int is_rsdp;
+uint8_t cksum;
 
 /* Check if rsdp signature match with the ACPI RSDP signature. */
-is_rsdp = acpi_check_signature(rsdp->signature, ACPI_RSDP_SIG, 
8*sizeof(uint8_t));
+is_rsdp = acpi_check_signature(rsdp->v1.signature, ACPI_RSDP_SIG, 
8*sizeof(uint8_t));
 
 if (is_rsdp != ACPI_SUCCESS)
 return ACPI_BAD_SIGNATURE;
 
-/* If match, calculates rdsp checksum and check It. */
-checksum = acpi_checksum(rsdp, sizeof(struct acpi_rsdp));
+if (rsdp->v1.revision == 0) {
+// ACPI 1.0
+*sdt_base = rsdp->v1.rsdt_addr;
+printf("ACPI v1.0\n");
+cksum = acpi_checksum((void *)(>v1), sizeof(struct acpi_rsdp));
 
-if (checksum != 0)
-return ACPI_BAD_CHECKSUM;
+if (cksum != 0)
+return ACPI_BAD_CHECKSUM;
 
-return ACPI_SUCCESS;
+return 1;
+
+} else if (rsdp->v1.revision == 2) {
+// ACPI >= 2.0
+*sdt_base = rsdp->xsdt_addr;
+printf("ACPI >= v2.0\n");
+cksum = acpi_checksum((void *)rsdp, sizeof(struct acpi_rsdp2));
+
+if (cksum != 0)
+return ACPI_BAD_CHECKSUM;
+
+return 2;
+}
+
+return ACPI_NO_RSDP;
 }
 
 /*
@@ -147,38 +164,41 @@ acpi_check_rsdp_align(void *addr)
  *
  * Preconditions: The start address (addr) must be aligned.
  *
- * Returns the reference to rsdp structure if success, NULL if failure.
+ * Returns the physical address of rsdp structure if success, 0 if failure.
  */
-static struct acpi_rsdp*
-acpi_search_rsdp(void *addr, uint32_t length)
+static phys_addr_t
+acpi_search_rsdp(void *addr, uint32_t length, int *is_64bit)
 {
 void *end;
+int version = 0;
+phys_addr_t sdt_base = 0;
 
 /* Search RDSP in memory space between addr and addr+lenght. */
 for (end = addr+length; addr < end; addr += ACPI_RSDP_ALIGN) {
 
 /* Check if the current memory block stores the RDSP. */
-if ((addr != NULL) && (acpi_check_rsdp(addr) == ACPI_SUCCESS)) {
-/* If yes, return RSDP address */
-return (struct acpi_rsdp*) addr;
+if ((addr != NULL) && ((version = acpi_check_rsdp(addr, _base)) > 
0)) {
+/* If yes, return RSDT/XSDT address */
+*is_64bit = (version == 2);
+return sdt_base;
 }
 }
 
-return NULL;
+return 0;
 }
 
 /*
  * acpi_get_rsdp: tries to find the RSDP table,
  * searching It in many memory ranges, as It's written in ACPI Specification.
  *
- * Returns the reference to RDSP structure if success, NULL if failure.
+ * Returns the reference to RDSP structure if success, 0 if failure.
  */
-static struct acpi_rsdp*
-acpi_get_rsdp(void)
+static phys_addr_t
+acpi_get_rsdp(int *is_64bit)
 {
 uint16_t *start = 0;
 phys_addr_t base = 0;
-struct acpi_rsdp *rsdp = NULL;
+phys_addr_t rsdp = 0;
 
 /* EDBA start address. */
 start = (uint16_t*) phystokv(0x040e);
@@ -186,40 +206,17 @@ acpi_get_rsdp(void)
 
 /* check alignment. */
 if (acpi_check_rsdp_align((void *)base) == ACPI_BAD_ALIGN)
-return NULL;
-rsdp = acpi_search_rsdp((void *)base, 1024);
+return 0;
+rsdp = acpi_search_rsdp((void *)base, 1024, is_64bit);
 
-if (rsdp == NULL) {
+if (rsdp == 0) {
 /* If RSDP isn't in EDBA, search in the BIOS read-only memory space 
between 0Eh and 0Fh */
-rsdp = acpi_search_rsdp((void 

Re: [PATCH v2 gnumach] ACPI: Support XSDT (ACPI >= v2.0)

2024-01-30 Thread Samuel Thibault
Damien Zammit, le mar. 30 janv. 2024 08:04:38 +, a ecrit:
> This enables gnumach to additionally parse the XSDT table
> if the revision of ACPI is 2.
> 
> NB: I removed a few checksum checks in acpi tables where
> there is no checksum present in the table.
> 
> TESTED: Still works on qemu (ACPI v1.0)
> TESTED: Works on a x86 board with XSDT (ACPI v2.0)
> 
> ---
>  i386/i386at/acpi_parse_apic.c | 243 ++
>  i386/i386at/acpi_parse_apic.h |  18 ++-
>  i386/i386at/model_dep.c   |   8 +-
>  3 files changed, 180 insertions(+), 89 deletions(-)
> 
> diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
> index 1aef53ed..476d846e 100644
> --- a/i386/i386at/acpi_parse_apic.c
> +++ b/i386/i386at/acpi_parse_apic.c
> @@ -43,13 +43,12 @@ unsigned lapic_addr;
>   * and the number of entries stored in RSDT.
>   */
>  void
> -acpi_print_info(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, int 
> acpi_rsdt_n)
> +acpi_print_info(phys_addr_t rsdp, void *rsdt, int acpi_rsdt_n)
>  {
>  
>  printf("ACPI:\n");
> -printf(" rsdp = %p; rsdp->rsdt_addr = %x\n", rsdp, rsdp->rsdt_addr);
> -printf(" rsdt = %p; rsdt->length = %x (n = %x)\n", rsdt, 
> rsdt->header.length,
> -   acpi_rsdt_n);
> +printf(" rsdp = 0x%lx\n", rsdp);
> +printf(" rsdt/xsdt = 0x%p (n = %d)\n", rsdt, acpi_rsdt_n);
>  }
>  
>  /*
> @@ -69,6 +68,8 @@ acpi_checksum(void *addr, uint32_t length)
>  for (i = 0; i < length; i++)
>  checksum += bytes[i];
>  
> +printf("checksum result = 0x%x\n", checksum);

leftover ;)

>  return checksum;
>  }
>  
> -/*
> - * acpi_check_rsdt: check if the RSDT initial address is correct
> - * checking its checksum.
> - *
> - * Receives as input a reference for the RSDT "candidate" table.
> - * Returns 0 if success.
> - *
> - * Preconditions: rsdp must not be NULL.
> - *
> - */
> -static int
> -acpi_check_rsdt(struct acpi_rsdt *rsdt)
> -{
> -uint8_t checksum;
> -
> -checksum = acpi_checksum(rsdt, rsdt->header.length);
> -
> -if (checksum != 0)
> -return ACPI_BAD_CHECKSUM;
> -
> -return ACPI_SUCCESS;
> -}

Don't we want to keep checking the rsdt checksum?

> @@ -264,6 +253,40 @@ acpi_get_rsdt(struct acpi_rsdp *rsdp, int* acpi_rsdt_n)
>  return rsdt;
>  }
>  
> +/*
> + * acpi_get_xsdt: Get XSDT table reference from RSDPv2 entries.
> + *
> + * Receives as input a reference for RSDPv2 table
> + * and a reference to store the number of entries of XSDT.
> + *
> + * Returns the reference to XSDT table if success, NULL if error.
> + */
> +static struct acpi_xsdt*
> +acpi_get_xsdt(phys_addr_t rsdp_phys, int* acpi_xsdt_n)
> +{
> +struct acpi_xsdt *xsdt = NULL;
> +int signature_check;
> +
> +xsdt = (struct acpi_xsdt*) kmem_map_aligned_table(rsdp_phys, 
> sizeof(struct acpi_xsdt), VM_PROT_READ);
> +
> +/* Check if the RSDT mapping is fine. */
> +if (xsdt == NULL)
> +return NULL;
> +
> +/* Check is rsdt signature is equals to ACPI RSDT signature. */
> +signature_check = acpi_check_signature(xsdt->header.signature, 
> ACPI_XSDT_SIG,
> +   4*sizeof(uint8_t));
> +
> +if (signature_check != ACPI_SUCCESS)
> +return NULL;

Probably this table has a checksum too?

> +/* Calculated number of elements stored in rsdt. */
> +*acpi_xsdt_n = (xsdt->header.length - sizeof(xsdt->header))
> +   / sizeof(xsdt->entry[0]);
> +
> +return xsdt;
> +}
> +
>  /*
>   * acpi_get_apic: get MADT/APIC table from RSDT entries.
>   *

> @@ -452,16 +512,9 @@ acpi_apic_parse_table(struct acpi_apic *apic)
>  static int
>  acpi_apic_setup(struct acpi_apic *apic)
>  {
> -int apic_checksum;
>  ApicLocalUnit* lapic_unit;
>  uint8_t ncpus, nioapics;
>  
> -/* Check the checksum of the APIC */
> -apic_checksum = acpi_checksum(apic, apic->header.length);
> -
> -if(apic_checksum != 0)
> -return ACPI_BAD_CHECKSUM;
> -

And here as well, we'd want to keep the checksum?

>  /* map common lapic address */
>  lapic_addr = apic->lapic_addr;
>  lapic_unit = kmem_map_aligned_table(apic->lapic_addr, 
> sizeof(ApicLocalUnit),

Samuel



[PATCH v2 gnumach] ACPI: Support XSDT (ACPI >= v2.0)

2024-01-30 Thread Damien Zammit
This enables gnumach to additionally parse the XSDT table
if the revision of ACPI is 2.

NB: I removed a few checksum checks in acpi tables where
there is no checksum present in the table.

TESTED: Still works on qemu (ACPI v1.0)
TESTED: Works on a x86 board with XSDT (ACPI v2.0)

---
 i386/i386at/acpi_parse_apic.c | 243 ++
 i386/i386at/acpi_parse_apic.h |  18 ++-
 i386/i386at/model_dep.c   |   8 +-
 3 files changed, 180 insertions(+), 89 deletions(-)

diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
index 1aef53ed..476d846e 100644
--- a/i386/i386at/acpi_parse_apic.c
+++ b/i386/i386at/acpi_parse_apic.c
@@ -43,13 +43,12 @@ unsigned lapic_addr;
  * and the number of entries stored in RSDT.
  */
 void
-acpi_print_info(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, int 
acpi_rsdt_n)
+acpi_print_info(phys_addr_t rsdp, void *rsdt, int acpi_rsdt_n)
 {
 
 printf("ACPI:\n");
-printf(" rsdp = %p; rsdp->rsdt_addr = %x\n", rsdp, rsdp->rsdt_addr);
-printf(" rsdt = %p; rsdt->length = %x (n = %x)\n", rsdt, 
rsdt->header.length,
-   acpi_rsdt_n);
+printf(" rsdp = 0x%lx\n", rsdp);
+printf(" rsdt/xsdt = 0x%p (n = %d)\n", rsdt, acpi_rsdt_n);
 }
 
 /*
@@ -69,6 +68,8 @@ acpi_checksum(void *addr, uint32_t length)
 for (i = 0; i < length; i++)
 checksum += bytes[i];
 
+printf("checksum result = 0x%x\n", checksum);
+
 return checksum;
 }
 
@@ -99,27 +100,45 @@ acpi_check_signature(const uint8_t table_signature[], 
const char *real_signature
  *
  * Preconditions: RSDP pointer must not be NULL.
  *
- * Returns 0 if correct.
+ * Returns 1 if ACPI 1.0 and sets sdt_base
+ * Returns 2 if ACPI >= 2.0 and sets sdt_base
  */
 static int8_t
-acpi_check_rsdp(struct acpi_rsdp *rsdp)
+acpi_check_rsdp(struct acpi_rsdp2 *rsdp, phys_addr_t *sdt_base)
 {
-uint32_t checksum;
 int is_rsdp;
+uint8_t cksum;
 
 /* Check if rsdp signature match with the ACPI RSDP signature. */
-is_rsdp = acpi_check_signature(rsdp->signature, ACPI_RSDP_SIG, 
8*sizeof(uint8_t));
+is_rsdp = acpi_check_signature(rsdp->v1.signature, ACPI_RSDP_SIG, 
8*sizeof(uint8_t));
 
 if (is_rsdp != ACPI_SUCCESS)
 return ACPI_BAD_SIGNATURE;
 
-/* If match, calculates rdsp checksum and check It. */
-checksum = acpi_checksum(rsdp, sizeof(struct acpi_rsdp));
+if (rsdp->v1.revision == 0) {
+// ACPI 1.0
+*sdt_base = rsdp->v1.rsdt_addr;
+printf("ACPI v1.0\n");
+cksum = acpi_checksum((void *)(>v1), sizeof(struct acpi_rsdp));
 
-if (checksum != 0)
-return ACPI_BAD_CHECKSUM;
+if (cksum != 0)
+return ACPI_BAD_CHECKSUM;
 
-return ACPI_SUCCESS;
+return 1;
+
+} else if (rsdp->v1.revision == 2) {
+// ACPI >= 2.0
+*sdt_base = rsdp->xsdt_addr;
+printf("ACPI >= v2.0\n");
+cksum = acpi_checksum((void *)rsdp, sizeof(struct acpi_rsdp2));
+
+if (cksum != 0)
+return ACPI_BAD_CHECKSUM;
+
+return 2;
+}
+
+return ACPI_NO_RSDP;
 }
 
 /*
@@ -147,38 +166,41 @@ acpi_check_rsdp_align(void *addr)
  *
  * Preconditions: The start address (addr) must be aligned.
  *
- * Returns the reference to rsdp structure if success, NULL if failure.
+ * Returns the physical address of rsdp structure if success, 0 if failure.
  */
-static struct acpi_rsdp*
-acpi_search_rsdp(void *addr, uint32_t length)
+static phys_addr_t
+acpi_search_rsdp(void *addr, uint32_t length, int *is_64bit)
 {
 void *end;
+int version = 0;
+phys_addr_t sdt_base = 0;
 
 /* Search RDSP in memory space between addr and addr+lenght. */
 for (end = addr+length; addr < end; addr += ACPI_RSDP_ALIGN) {
 
 /* Check if the current memory block stores the RDSP. */
-if ((addr != NULL) && (acpi_check_rsdp(addr) == ACPI_SUCCESS)) {
-/* If yes, return RSDP address */
-return (struct acpi_rsdp*) addr;
+if ((addr != NULL) && ((version = acpi_check_rsdp(addr, _base)) > 
0)) {
+/* If yes, return RSDT/XSDT address */
+*is_64bit = (version == 2);
+return sdt_base;
 }
 }
 
-return NULL;
+return 0;
 }
 
 /*
  * acpi_get_rsdp: tries to find the RSDP table,
  * searching It in many memory ranges, as It's written in ACPI Specification.
  *
- * Returns the reference to RDSP structure if success, NULL if failure.
+ * Returns the reference to RDSP structure if success, 0 if failure.
  */
-static struct acpi_rsdp*
-acpi_get_rsdp(void)
+static phys_addr_t
+acpi_get_rsdp(int *is_64bit)
 {
 uint16_t *start = 0;
 phys_addr_t base = 0;
-struct acpi_rsdp *rsdp = NULL;
+phys_addr_t rsdp = 0;
 
 /* EDBA start address. */
 start = (uint16_t*) phystokv(0x040e);
@@ -186,40 +208,17 @@ acpi_get_rsdp(void)
 
 /* check alignment. */
 if (acpi_check_rsdp_align((void *)base) == ACPI_BAD_ALIGN)
-return NULL;
-rsdp = 

Re: [PATCH 2/2 gnumach] ACPI: Support XSDT (ACPI >= v2.0)

2024-01-27 Thread Samuel Thibault
Hello,

Damien Zammit, le mer. 24 janv. 2024 03:52:03 +, a ecrit:
> diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
> index 9cd861ed..7b377d33 100644
> --- a/i386/i386at/acpi_parse_apic.c
> +++ b/i386/i386at/acpi_parse_apic.c
> @@ -99,27 +98,33 @@ acpi_check_signature(const uint8_t table_signature[], 
> const char *real_signature
>   *
>   * Preconditions: RSDP pointer must not be NULL.
>   *
> - * Returns 0 if correct.
> + * Returns 1 if ACPI 1.0 and sets sdt_base
> + * Returns 2 if ACPI >= 2.0 and sets sdt_base
>   */
>  static int8_t
> -acpi_check_rsdp(struct acpi_rsdp *rsdp)
> +acpi_check_rsdp(struct acpi_rsdp2 *rsdp, phys_addr_t *sdt_base)
>  {
> -uint32_t checksum;
>  int is_rsdp;
>  
>  /* Check if rsdp signature match with the ACPI RSDP signature. */
> -is_rsdp = acpi_check_signature(rsdp->signature, ACPI_RSDP_SIG, 
> 8*sizeof(uint8_t));
> +is_rsdp = acpi_check_signature(rsdp->v1.signature, ACPI_RSDP_SIG, 
> 8*sizeof(uint8_t));
>  
>  if (is_rsdp != ACPI_SUCCESS)
>  return ACPI_BAD_SIGNATURE;
>  
> -/* If match, calculates rdsp checksum and check It. */
> -checksum = acpi_checksum(rsdp, sizeof(struct acpi_rsdp));
> -
> -if (checksum != 0)
> -return ACPI_BAD_CHECKSUM;

Don't we want to still check the checksum?
(possibly fix it for the acpi 2.0 case)

> +if (rsdp->v1.revision == 0) {
> +// ACPI 1.0
> +*sdt_base = rsdp->v1.rsdt_addr;
> +printf("ACPI v1.0\n");
> +return 1;
> +} else if (rsdp->v1.revision == 2) {
> +// ACPI >= 2.0
> +*sdt_base = rsdp->xsdt_addr;
> +printf("ACPI >= v2.0\n");
> +return 2;
> +}
>  
> -return ACPI_SUCCESS;
> +return ACPI_NO_RSDP;
>  }
>  
>  /*
> @@ -147,38 +152,43 @@ acpi_check_rsdp_align(void *addr)
>   *
>   * Preconditions: The start address (addr) must be aligned.
>   *
> - * Returns the reference to rsdp structure if success, NULL if failure.
> + * Returns the physical address of rsdp structure if success, 0 if failure.
>   */
> -static struct acpi_rsdp*
> -acpi_search_rsdp(void *addr, uint32_t length)
> +static phys_addr_t
> +acpi_search_rsdp(void *addr, uint32_t length, int *is_64bit)
>  {
>  void *end;
> +int version = 0;

There is no need to initialize version.

> +phys_addr_t sdt_base = 0;
>  
>  /* Search RDSP in memory space between addr and addr+lenght. */
>  for (end = addr+length; addr < end; addr += ACPI_RSDP_ALIGN) {
>  
>  /* Check if the current memory block stores the RDSP. */
> -if ((addr != NULL) && (acpi_check_rsdp(addr) == ACPI_SUCCESS)) {
> -/* If yes, return RSDP address */
> -return (struct acpi_rsdp*) addr;
> +if ((addr != NULL) && ((version = acpi_check_rsdp(addr, _base)) 
> > 0)) {
> +/* If yes, return RSDT/XSDT address */
> +*is_64bit = 0;
> +if (version == 2)
> +*is_64bit = 1;

You can make this *is_64bit = version == 2;

> @@ -449,16 +527,9 @@ acpi_apic_parse_table(struct acpi_apic *apic)
>  static int
>  acpi_apic_setup(struct acpi_apic *apic)
>  {
> -int apic_checksum;
>  ApicLocalUnit* lapic_unit;
>  uint8_t ncpus, nioapics;
>  
> -/* Check the checksum of the APIC */
> -apic_checksum = acpi_checksum(apic, apic->header.length);
> -
> -if(apic_checksum != 0)
> -return ACPI_BAD_CHECKSUM;

Here as well we'd rather keep checking the checksum?

Samuel



[PATCH 2/2 gnumach] ACPI: Support XSDT (ACPI >= v2.0)

2024-01-23 Thread Damien Zammit
---
 i386/i386at/acpi_parse_apic.c | 203 --
 i386/i386at/acpi_parse_apic.h |  18 ++-
 i386/i386at/model_dep.c   |   8 +-
 3 files changed, 169 insertions(+), 60 deletions(-)

diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
index 9cd861ed..7b377d33 100644
--- a/i386/i386at/acpi_parse_apic.c
+++ b/i386/i386at/acpi_parse_apic.c
@@ -43,13 +43,12 @@ unsigned lapic_addr;
  * and the number of entries stored in RSDT.
  */
 void
-acpi_print_info(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, int 
acpi_rsdt_n)
+acpi_print_info(phys_addr_t rsdp, void *rsdt, int acpi_rsdt_n)
 {
 
 printf("ACPI:\n");
-printf(" rsdp = %p; rsdp->rsdt_addr = %x\n", rsdp, rsdp->rsdt_addr);
-printf(" rsdt = %p; rsdt->length = %x (n = %x)\n", rsdt, 
rsdt->header.length,
-   acpi_rsdt_n);
+printf(" rsdp = 0x%lx\n", rsdp);
+printf(" rsdt/xsdt = 0x%p (n = %d)\n", rsdt, acpi_rsdt_n);
 }
 
 /*
@@ -99,27 +98,33 @@ acpi_check_signature(const uint8_t table_signature[], const 
char *real_signature
  *
  * Preconditions: RSDP pointer must not be NULL.
  *
- * Returns 0 if correct.
+ * Returns 1 if ACPI 1.0 and sets sdt_base
+ * Returns 2 if ACPI >= 2.0 and sets sdt_base
  */
 static int8_t
-acpi_check_rsdp(struct acpi_rsdp *rsdp)
+acpi_check_rsdp(struct acpi_rsdp2 *rsdp, phys_addr_t *sdt_base)
 {
-uint32_t checksum;
 int is_rsdp;
 
 /* Check if rsdp signature match with the ACPI RSDP signature. */
-is_rsdp = acpi_check_signature(rsdp->signature, ACPI_RSDP_SIG, 
8*sizeof(uint8_t));
+is_rsdp = acpi_check_signature(rsdp->v1.signature, ACPI_RSDP_SIG, 
8*sizeof(uint8_t));
 
 if (is_rsdp != ACPI_SUCCESS)
 return ACPI_BAD_SIGNATURE;
 
-/* If match, calculates rdsp checksum and check It. */
-checksum = acpi_checksum(rsdp, sizeof(struct acpi_rsdp));
-
-if (checksum != 0)
-return ACPI_BAD_CHECKSUM;
+if (rsdp->v1.revision == 0) {
+// ACPI 1.0
+*sdt_base = rsdp->v1.rsdt_addr;
+printf("ACPI v1.0\n");
+return 1;
+} else if (rsdp->v1.revision == 2) {
+// ACPI >= 2.0
+*sdt_base = rsdp->xsdt_addr;
+printf("ACPI >= v2.0\n");
+return 2;
+}
 
-return ACPI_SUCCESS;
+return ACPI_NO_RSDP;
 }
 
 /*
@@ -147,38 +152,43 @@ acpi_check_rsdp_align(void *addr)
  *
  * Preconditions: The start address (addr) must be aligned.
  *
- * Returns the reference to rsdp structure if success, NULL if failure.
+ * Returns the physical address of rsdp structure if success, 0 if failure.
  */
-static struct acpi_rsdp*
-acpi_search_rsdp(void *addr, uint32_t length)
+static phys_addr_t
+acpi_search_rsdp(void *addr, uint32_t length, int *is_64bit)
 {
 void *end;
+int version = 0;
+phys_addr_t sdt_base = 0;
 
 /* Search RDSP in memory space between addr and addr+lenght. */
 for (end = addr+length; addr < end; addr += ACPI_RSDP_ALIGN) {
 
 /* Check if the current memory block stores the RDSP. */
-if ((addr != NULL) && (acpi_check_rsdp(addr) == ACPI_SUCCESS)) {
-/* If yes, return RSDP address */
-return (struct acpi_rsdp*) addr;
+if ((addr != NULL) && ((version = acpi_check_rsdp(addr, _base)) > 
0)) {
+/* If yes, return RSDT/XSDT address */
+*is_64bit = 0;
+if (version == 2)
+*is_64bit = 1;
+return sdt_base;
 }
 }
 
-return NULL;
+return 0;
 }
 
 /*
  * acpi_get_rsdp: tries to find the RSDP table,
  * searching It in many memory ranges, as It's written in ACPI Specification.
  *
- * Returns the reference to RDSP structure if success, NULL if failure.
+ * Returns the reference to RDSP structure if success, 0 if failure.
  */
-static struct acpi_rsdp*
-acpi_get_rsdp(void)
+static phys_addr_t
+acpi_get_rsdp(int *is_64bit)
 {
 uint16_t *start = 0;
 phys_addr_t base = 0;
-struct acpi_rsdp *rsdp = NULL;
+phys_addr_t rsdp = 0;
 
 /* EDBA start address. */
 start = (uint16_t*) phystokv(0x040e);
@@ -186,12 +196,12 @@ acpi_get_rsdp(void)
 
 /* check alignment. */
 if (acpi_check_rsdp_align((void *)base) == ACPI_BAD_ALIGN)
-return NULL;
-rsdp = acpi_search_rsdp((void *)base, 1024);
+return 0;
+rsdp = acpi_search_rsdp((void *)base, 1024, is_64bit);
 
-if (rsdp == NULL) {
+if (rsdp == 0) {
 /* If RSDP isn't in EDBA, search in the BIOS read-only memory space 
between 0Eh and 0Fh */
-rsdp = acpi_search_rsdp((void *)phystokv(0xe), 0x10 - 
0x0e);
+rsdp = acpi_search_rsdp((void *)phystokv(0xe), 0x10 - 
0x0e, is_64bit);
 }
 
 return rsdp;
@@ -229,16 +239,13 @@ acpi_check_rsdt(struct acpi_rsdt *rsdt)
  * Returns the reference to RSDT table if success, NULL if error.
  */
 static struct acpi_rsdt*
-acpi_get_rsdt(struct acpi_rsdp *rsdp, int* acpi_rsdt_n)
+acpi_get_rsdt(phys_addr_t rsdp_phys, int* acpi_rsdt_n)
 {
-

Re: ACPI support

2020-04-25 Thread Samuel Thibault
Hello,

Damien Zammit, le sam. 25 avril 2020 09:38:31 +1000, a ecrit:
> http://git.zammit.org/gnumach-sv.git/log/?h=debian-acpica
> 
> It boots and prints a log but the problem I am facing is that
> the log is not saved to /var/log/dmesg even though it prints at boot.
> As it scrolls so fast, I cannot read it and I don't know how to have
> it captured to the kernel log file.

You can cat /dev/klog

Samuel



ACPI support

2020-04-24 Thread Damien Zammit
Hi all,

I have added ACPICA support to gnumach here:

http://git.zammit.org/gnumach-sv.git/log/?h=debian-acpica

It boots and prints a log but the problem I am facing is that
the log is not saved to /var/log/dmesg even though it prints at boot.
As it scrolls so fast, I cannot read it and I don't know how to have
it captured to the kernel log file.

Any thoughts?

Thanks,
Damien